<commit_before>(function() {
  "use strict";
  var GUTTER_ID = "CodeMirror-lint-markers";
  var SEVERITIES = /^(?:error|warning)$/;

  function showTooltip(e, content) {
    var tt = document.createElement("div");
    tt.className = "CodeMirror-lint-tooltip";
    tt.appendChild(content.cloneNode(true));
    document.body.appendChild(tt);

    function position(e) {
      if (!tt.parentNode) return CodeMirror.off(document, "mousemove", position);
      tt.style.top = Math.max(0, e.clientY - tt.offsetHeight - 5) + "px";
      tt.style.left = (e.clientX + 5) + "px";
    }
    CodeMirror.on(document, "mousemove", position);
    position(e);
    if (tt.style.opacity != null) tt.style.opacity = 1;
    return tt;
  }
  function rm(elt) {
    if (elt.parentNode) elt.parentNode.removeChild(elt);
  }
  function hideTooltip(tt) {
    if (!tt.parentNode) return;
    if (tt.style.opacity == null) rm(tt);
    tt.style.opacity = 0;
    setTimeout(function() { rm(tt); }, 600);
  }

  function showTooltipFor(e, content, node) {
    var tooltip = showTooltip(e, content);
    function hide() {
      CodeMirror.off(node, "mouseout", hide);
      if (tooltip) { hideTooltip(tooltip); tooltip = null; }
    }
    var poll = setInterval(function() {
      if (tooltip) for (var n = node;; n = n.parentNode) {
        if (n == document.body) return;
        if (!n) { hide(); break; }
      }
      if (!tooltip) return clearInterval(poll);
    }, 400);
    CodeMirror.on(node, "mouseout", hide);
  }

  function LintState(cm, options, hasGutter) {
    this.marked = [];
    this.options = options;
    this.timeout = null;
    this.hasGutter = hasGutter;
    this.onMouseOver = function(e) { onMouseOver(cm, e); };
  }

  function parseOptions(cm, options) {
    if (options instanceof Function) return {getAnnotations: options};
    if (!options || options === true) options = {};
    if (!options.getAnnotations) options.getAnnotations = cm.getHelper(CodeMirror.Pos(0, 0), "lint");
    if (!options.getAnnotations) throw new Error("Required option 'getAnnotations' missing (lint addon)");
    return options;
  }

  function clearMarks(cm) {
    var state = cm.state.lint;
    if (state.hasGutter) cm.clearGutter(GUTTER_ID);
    for (var i = 0; i < state.marked.length; ++i)
      state.marked[i].clear();
    state.marked.length = 0;
  }

  function makeMarker(labels, severity, multiple, tooltips) {
    var marker = document.createElement("div"), inner = marker;
    marker.className = "CodeMirror-lint-marker-" + severity;
    if (multiple) {
      inner = marker.appendChild(document.createElement("div"));
      inner.className = "CodeMirror-lint-marker-multiple";
    }

    if (tooltips != false) CodeMirror.on(inner, "mouseover", function(e) {
      showTooltipFor(e, labels, inner);
    });

    return marker;
  }

  function getMaxSeverity(a, b) {
    if (a == "error") return a;
    else return b;
  }

  function groupByLine(annotations) {
    var lines = [];
    for (var i = 0; i < annotations.length; ++i) {
      var ann = annotations[i], line = ann.from.line;
      (lines[line] || (lines[line] = [])).push(ann);
    }
    return lines;
  }

  function annotationTooltip(ann) {
    var severity = ann.severity;
    if (!SEVERITIES.test(severity)) severity = "error";
    var tip = document.createElement("div");
    tip.className = "CodeMirror-lint-message-" + severity;
    tip.appendChild(document.createTextNode(ann.message));
    return tip;
  }

  function startLinting(cm) {
    var state = cm.state.lint, options = state.options;
    if (options.async)
      options.getAnnotations(cm, updateLinting, options);
    else
      updateLinting(cm, options.getAnnotations(cm.getValue()));
  }

  function updateLinting(cm, annotationsNotSorted) {
    clearMarks(cm);
    var state = cm.state.lint, options = state.options;

    var annotations = groupByLine(annotationsNotSorted);

    for (var line = 0; line < annotations.length; ++line) {
      var anns = annotations[line];
      if (!anns) continue;

      var maxSeverity = null;
      var tipLabel = state.hasGutter && document.createDocumentFragment();

      for (var i = 0; i < anns.length; ++i) {
        var ann = anns[i];
        var severity = ann.severity;
        if (!SEVERITIES.test(severity)) severity = "error";
        maxSeverity = getMaxSeverity(maxSeverity, severity);

        if (options.formatAnnotation) ann = options.formatAnnotation(ann);
        if (state.hasGutter) tipLabel.appendChild(annotationTooltip(ann));

        if (ann.to) state.marked.push(cm.markText(ann.from, ann.to, {
          className: "CodeMirror-lint-mark-" + severity,
          __annotation: ann
        }));
      }

      if (state.hasGutter)
        cm.setGutterMarker(line, GUTTER_ID, makeMarker(tipLabel, maxSeverity, anns.length > 1,
                                                       state.options.tooltips));
    }
    if (options.onUpdateLinting) options.onUpdateLinting(annotationsNotSorted, annotations, cm);
  }

  function onChange(cm) {
    var state = cm.state.lint;
    clearTimeout(state.timeout);
    state.timeout = setTimeout(function(){startLinting(cm);}, state.options.delay || 500);
  }

  function popupSpanTooltip(ann, e) {
    var target = e.target || e.srcElement;
    showTooltipFor(e, annotationTooltip(ann), target);
  }

  // When the mouseover fires, the cursor might not actually be over
  // the character itself yet. These pairs of x,y offsets are used to
  // probe a few nearby points when no suitable marked range is found.
  var nearby = [0, 0, 0, 5, 0, -5, 5, 0, -5, 0];

  function onMouseOver(cm, e) {
    if (!/\bCodeMirror-lint-mark-/.test((e.target || e.srcElement).className)) return;
    for (var i = 0; i < nearby.length; i += 2) {
      var spans = cm.findMarksAt(cm.coordsChar({left: e.clientX + nearby[i],
                                                top: e.clientY + nearby[i + 1]}));
      for (var j = 0; j < spans.length; ++j) {
        var span = spans[j], ann = span.__annotation;
        if (ann) return popupSpanTooltip(ann, e);
      }
    }
  }

  function optionHandler(cm, val, old) {
    if (old && old != CodeMirror.Init) {
      clearMarks(cm);
      cm.off("change", onChange);
      CodeMirror.off(cm.getWrapperElement(), "mouseover", cm.state.lint.onMouseOver);
      delete cm.state.lint;
    }

    if (val) {
      var gutters = cm.getOption("gutters"), hasLintGutter = false;
      for (var i = 0; i < gutters.length; ++i) if (gutters[i] == GUTTER_ID) hasLintGutter = true;
      var state = cm.state.lint = new LintState(cm, parseOptions(cm, val), hasLintGutter);
      cm.on("change", onChange);
      if (state.options.tooltips != false)
        CodeMirror.on(cm.getWrapperElement(), "mouseover", state.onMouseOver);

      startLinting(cm);
    }
  }

  CodeMirror.defineOption("lintWith", false, optionHandler); // deprecated
  CodeMirror.defineOption("lint", false, optionHandler); // deprecated
})();
<commit_msg>[lint addon] Pass lint options on when not in async mode<commit_after>(function() {
  "use strict";
  var GUTTER_ID = "CodeMirror-lint-markers";
  var SEVERITIES = /^(?:error|warning)$/;

  function showTooltip(e, content) {
    var tt = document.createElement("div");
    tt.className = "CodeMirror-lint-tooltip";
    tt.appendChild(content.cloneNode(true));
    document.body.appendChild(tt);

    function position(e) {
      if (!tt.parentNode) return CodeMirror.off(document, "mousemove", position);
      tt.style.top = Math.max(0, e.clientY - tt.offsetHeight - 5) + "px";
      tt.style.left = (e.clientX + 5) + "px";
    }
    CodeMirror.on(document, "mousemove", position);
    position(e);
    if (tt.style.opacity != null) tt.style.opacity = 1;
    return tt;
  }
  function rm(elt) {
    if (elt.parentNode) elt.parentNode.removeChild(elt);
  }
  function hideTooltip(tt) {
    if (!tt.parentNode) return;
    if (tt.style.opacity == null) rm(tt);
    tt.style.opacity = 0;
    setTimeout(function() { rm(tt); }, 600);
  }

  function showTooltipFor(e, content, node) {
    var tooltip = showTooltip(e, content);
    function hide() {
      CodeMirror.off(node, "mouseout", hide);
      if (tooltip) { hideTooltip(tooltip); tooltip = null; }
    }
    var poll = setInterval(function() {
      if (tooltip) for (var n = node;; n = n.parentNode) {
        if (n == document.body) return;
        if (!n) { hide(); break; }
      }
      if (!tooltip) return clearInterval(poll);
    }, 400);
    CodeMirror.on(node, "mouseout", hide);
  }

  function LintState(cm, options, hasGutter) {
    this.marked = [];
    this.options = options;
    this.timeout = null;
    this.hasGutter = hasGutter;
    this.onMouseOver = function(e) { onMouseOver(cm, e); };
  }

  function parseOptions(cm, options) {
    if (options instanceof Function) return {getAnnotations: options};
    if (!options || options === true) options = {};
    if (!options.getAnnotations) options.getAnnotations = cm.getHelper(CodeMirror.Pos(0, 0), "lint");
    if (!options.getAnnotations) throw new Error("Required option 'getAnnotations' missing (lint addon)");
    return options;
  }

  function clearMarks(cm) {
    var state = cm.state.lint;
    if (state.hasGutter) cm.clearGutter(GUTTER_ID);
    for (var i = 0; i < state.marked.length; ++i)
      state.marked[i].clear();
    state.marked.length = 0;
  }

  function makeMarker(labels, severity, multiple, tooltips) {
    var marker = document.createElement("div"), inner = marker;
    marker.className = "CodeMirror-lint-marker-" + severity;
    if (multiple) {
      inner = marker.appendChild(document.createElement("div"));
      inner.className = "CodeMirror-lint-marker-multiple";
    }

    if (tooltips != false) CodeMirror.on(inner, "mouseover", function(e) {
      showTooltipFor(e, labels, inner);
    });

    return marker;
  }

  function getMaxSeverity(a, b) {
    if (a == "error") return a;
    else return b;
  }

  function groupByLine(annotations) {
    var lines = [];
    for (var i = 0; i < annotations.length; ++i) {
      var ann = annotations[i], line = ann.from.line;
      (lines[line] || (lines[line] = [])).push(ann);
    }
    return lines;
  }

  function annotationTooltip(ann) {
    var severity = ann.severity;
    if (!SEVERITIES.test(severity)) severity = "error";
    var tip = document.createElement("div");
    tip.className = "CodeMirror-lint-message-" + severity;
    tip.appendChild(document.createTextNode(ann.message));
    return tip;
  }

  function startLinting(cm) {
    var state = cm.state.lint, options = state.options;
    if (options.async)
      options.getAnnotations(cm, updateLinting, options);
    else
      updateLinting(cm, options.getAnnotations(cm.getValue(), options));
  }

  function updateLinting(cm, annotationsNotSorted) {
    clearMarks(cm);
    var state = cm.state.lint, options = state.options;

    var annotations = groupByLine(annotationsNotSorted);

    for (var line = 0; line < annotations.length; ++line) {
      var anns = annotations[line];
      if (!anns) continue;

      var maxSeverity = null;
      var tipLabel = state.hasGutter && document.createDocumentFragment();

      for (var i = 0; i < anns.length; ++i) {
        var ann = anns[i];
        var severity = ann.severity;
        if (!SEVERITIES.test(severity)) severity = "error";
        maxSeverity = getMaxSeverity(maxSeverity, severity);

        if (options.formatAnnotation) ann = options.formatAnnotation(ann);
        if (state.hasGutter) tipLabel.appendChild(annotationTooltip(ann));

        if (ann.to) state.marked.push(cm.markText(ann.from, ann.to, {
          className: "CodeMirror-lint-mark-" + severity,
          __annotation: ann
        }));
      }

      if (state.hasGutter)
        cm.setGutterMarker(line, GUTTER_ID, makeMarker(tipLabel, maxSeverity, anns.length > 1,
                                                       state.options.tooltips));
    }
    if (options.onUpdateLinting) options.onUpdateLinting(annotationsNotSorted, annotations, cm);
  }

  function onChange(cm) {
    var state = cm.state.lint;
    clearTimeout(state.timeout);
    state.timeout = setTimeout(function(){startLinting(cm);}, state.options.delay || 500);
  }

  function popupSpanTooltip(ann, e) {
    var target = e.target || e.srcElement;
    showTooltipFor(e, annotationTooltip(ann), target);
  }

  // When the mouseover fires, the cursor might not actually be over
  // the character itself yet. These pairs of x,y offsets are used to
  // probe a few nearby points when no suitable marked range is found.
  var nearby = [0, 0, 0, 5, 0, -5, 5, 0, -5, 0];

  function onMouseOver(cm, e) {
    if (!/\bCodeMirror-lint-mark-/.test((e.target || e.srcElement).className)) return;
    for (var i = 0; i < nearby.length; i += 2) {
      var spans = cm.findMarksAt(cm.coordsChar({left: e.clientX + nearby[i],
                                                top: e.clientY + nearby[i + 1]}));
      for (var j = 0; j < spans.length; ++j) {
        var span = spans[j], ann = span.__annotation;
        if (ann) return popupSpanTooltip(ann, e);
      }
    }
  }

  function optionHandler(cm, val, old) {
    if (old && old != CodeMirror.Init) {
      clearMarks(cm);
      cm.off("change", onChange);
      CodeMirror.off(cm.getWrapperElement(), "mouseover", cm.state.lint.onMouseOver);
      delete cm.state.lint;
    }

    if (val) {
      var gutters = cm.getOption("gutters"), hasLintGutter = false;
      for (var i = 0; i < gutters.length; ++i) if (gutters[i] == GUTTER_ID) hasLintGutter = true;
      var state = cm.state.lint = new LintState(cm, parseOptions(cm, val), hasLintGutter);
      cm.on("change", onChange);
      if (state.options.tooltips != false)
        CodeMirror.on(cm.getWrapperElement(), "mouseover", state.onMouseOver);

      startLinting(cm);
    }
  }

  CodeMirror.defineOption("lintWith", false, optionHandler); // deprecated
  CodeMirror.defineOption("lint", false, optionHandler); // deprecated
})();
<|endoftext|>


<commit_before>'use strict';

var fs              = require('fs-extra');
var path            = require('path');
var Builder         = require('../../../lib/models/builder');
var BuildCommand    = require('../../../lib/commands/build');
var commandOptions  = require('../../factories/command-options');
var touch           = require('../../helpers/file-utils').touch;
var assert          = require('assert');
var Promise         = require('../../../lib/ext/promise');
var stub            = require('../../helpers/stub').stub;
var MockProject     = require('../../helpers/mock-project');
var rimraf          = Promise.denodeify(require('rimraf'));
var tmp             = require('tmp-sync');

var root            = process.cwd();
var tmproot         = path.join(root, 'tmp');

describe('models/builder.js', function() {
  var addon, builder, buildResults, outputPath, tmpdir;

  describe('copyToOutputPath', function() {
    beforeEach(function() {
      tmpdir  = tmp.in(tmproot);

      builder = new Builder({
        setupBroccoliBuilder: function() { },
        trapSignals: function() { },
        cleanupOnExit: function() { },
        project: new MockProject()
      });
    });

    afterEach(function() {
      return rimraf(tmproot);
    });

    it('allows for non-existent output-paths at arbitrary depth', function() {
      builder.outputPath = path.join(tmpdir, 'some', 'path', 'that', 'does', 'not', 'exist');

      return builder.copyToOutputPath('tests/fixtures/blueprints/basic_2')
        .then(function() {
          assert(fs.existsSync(path.join(builder.outputPath, 'files', 'foo.txt')));
        });
    });
  });

  it('clears the outputPath when multiple files are present', function() {
    outputPath     = 'tmp/builder-fixture/';
    var firstFile  = outputPath + '/assets/foo-bar.js';
    var secondFile = outputPath + '/assets/baz-bif.js';

    fs.mkdirsSync(outputPath + '/assets/');
    touch(firstFile);
    touch(secondFile);

    builder = new Builder({
      setupBroccoliBuilder: function() { },
      trapSignals:          function() { },
      cleanupOnExit:        function() { },

      outputPath: outputPath,
      project: new MockProject()
    });

    return builder.clearOutputPath()
      .then(function() {
        assert(!fs.existsSync(firstFile));
        assert(!fs.existsSync(secondFile));
      });
  });

  describe('Prevent deletion of files for improper outputPath', function() {
    var command;

    before(function() {
      command = new BuildCommand(commandOptions({
        settings: {}
      }));

      builder = new Builder({
        setupBroccoliBuilder: function() { },
        trapSignals: function() { },
        cleanupOnExit: function() { },
        project: new MockProject()
      });
    });

    it('when outputPath is root directory ie., `--output-path=/`', function() {
      var outputPathArg = '--output-path=/';
      var outputPath = command.parseArgs([outputPathArg]).options.outputPath;
      builder.outputPath = outputPath;

      return builder.clearOutputPath()
        .catch(function(error) {
          assert.equal(error.message, 'Using a build destination path of `' + outputPath + '` is not supported.');
        });
    });

    it('when outputPath is project root ie., `--output-path=.`', function() {
      var outputPathArg = '--output-path=.';
      var outputPath = command.parseArgs([outputPathArg]).options.outputPath;
      builder.outputPath = outputPath;

      return builder.clearOutputPath()
        .catch(function(error) {
          assert.equal(error.message, 'Using a build destination path of `' + outputPath + '` is not supported.');
        });
    });

    it('when outputPath is a parent directory ie., `--output-path=../../`', function() {
      var outputPathArg = '--output-path=../../';
      var outputPath = command.parseArgs([outputPathArg]).options.outputPath;
      builder.outputPath = outputPath;

      return builder.clearOutputPath()
        .catch(function(error) {
          assert.equal(error.message, 'Using a build destination path of `' + outputPath + '` is not supported.');
        });
    });
  });

  describe('addons', function() {

    before(function() {
      addon = {
        name: 'TestAddon',
        preBuild: function() { },
        postBuild: function() { }
      };

      builder = new Builder({
        setupBroccoliBuilder: function() { },
        trapSignals:          function() { },
        cleanupOnExit:        function() { },
        builder: {
          build: function() { return Promise.resolve(buildResults); }
        },
        processBuildResult: function(buildResults) { return Promise.resolve(buildResults); },
        project: {
          addons: [addon]
        }
      });

      buildResults = 'build results';
    });

    it('allows addons to add promises prebuild', function() {
      var preBuild = stub(addon, 'preBuild');

      return builder.build().then(function() {
        assert.equal(preBuild.called, 1, 'expected preBuild to be called');
        assert.equal(preBuild.calledWith[0][0], buildResults, 'expected preBuild to be called with the results');
      });
    });

    it('allows addons to add promises postbuild', function() {
      var postBuild = stub(addon, 'postBuild');

      return builder.build().then(function() {
        assert.equal(postBuild.called, 1, 'expected postBuild to be called');
        assert.equal(postBuild.calledWith[0][0], buildResults, 'expected postBuild to be called with the results');
      });
    });
  });
});
<commit_msg>Fix camelCasing in builder tests<commit_after>'use strict';

var fs              = require('fs-extra');
var path            = require('path');
var Builder         = require('../../../lib/models/builder');
var BuildCommand    = require('../../../lib/commands/build');
var commandOptions  = require('../../factories/command-options');
var touch           = require('../../helpers/file-utils').touch;
var assert          = require('assert');
var Promise         = require('../../../lib/ext/promise');
var stub            = require('../../helpers/stub').stub;
var MockProject     = require('../../helpers/mock-project');
var rimraf          = Promise.denodeify(require('rimraf'));
var tmp             = require('tmp-sync');

var root            = process.cwd();
var tmproot         = path.join(root, 'tmp');

describe('models/builder.js', function() {
  var addon, builder, buildResults, outputPath, tmpdir;

  describe('copyToOutputPath', function() {
    beforeEach(function() {
      tmpdir  = tmp.in(tmproot);

      builder = new Builder({
        setupBroccoliBuilder: function() { },
        trapSignals: function() { },
        cleanupOnExit: function() { },
        project: new MockProject()
      });
    });

    afterEach(function() {
      return rimraf(tmproot);
    });

    it('allows for non-existent output-paths at arbitrary depth', function() {
      builder.outputPath = path.join(tmpdir, 'some', 'path', 'that', 'does', 'not', 'exist');

      return builder.copyToOutputPath('tests/fixtures/blueprints/basic_2')
        .then(function() {
          assert(fs.existsSync(path.join(builder.outputPath, 'files', 'foo.txt')));
        });
    });
  });

  it('clears the outputPath when multiple files are present', function() {
    outputPath     = 'tmp/builder-fixture/';
    var firstFile  = outputPath + '/assets/foo-bar.js';
    var secondFile = outputPath + '/assets/baz-bif.js';

    fs.mkdirsSync(outputPath + '/assets/');
    touch(firstFile);
    touch(secondFile);

    builder = new Builder({
      setupBroccoliBuilder: function() { },
      trapSignals:          function() { },
      cleanupOnExit:        function() { },

      outputPath: outputPath,
      project: new MockProject()
    });

    return builder.clearOutputPath()
      .then(function() {
        assert(!fs.existsSync(firstFile));
        assert(!fs.existsSync(secondFile));
      });
  });

  describe('Prevent deletion of files for improper outputPath', function() {
    var command;

    before(function() {
      command = new BuildCommand(commandOptions({
        settings: {}
      }));

      builder = new Builder({
        setupBroccoliBuilder: function() { },
        trapSignals: function() { },
        cleanupOnExit: function() { },
        project: new MockProject()
      });
    });

    it('when outputPath is root directory ie., `--output-path=/`', function() {
      var outputPathArg = '--output-path=/';
      var outputPath = command.parseArgs([outputPathArg]).options.outputPath;
      builder.outputPath = outputPath;

      return builder.clearOutputPath()
        .catch(function(error) {
          assert.equal(error.message, 'Using a build destination path of `' + outputPath + '` is not supported.');
        });
    });

    it('when outputPath is project root ie., `--output-path=.`', function() {
      var outputPathArg = '--output-path=.';
      var outputPath = command.parseArgs([outputPathArg]).options.outputPath;
      builder.outputPath = outputPath;

      return builder.clearOutputPath()
        .catch(function(error) {
          assert.equal(error.message, 'Using a build destination path of `' + outputPath + '` is not supported.');
        });
    });

    it('when outputPath is a parent directory ie., `--output-path=../../`', function() {
      var outputPathArg = '--output-path=../../';
      var outputPath = command.parseArgs([outputPathArg]).options.outputPath;
      builder.outputPath = outputPath;

      return builder.clearOutputPath()
        .catch(function(error) {
          assert.equal(error.message, 'Using a build destination path of `' + outputPath + '` is not supported.');
        });
    });
  });

  describe('addons', function() {

    before(function() {
      addon = {
        name: 'TestAddon',
        preBuild: function() { },
        postBuild: function() { }
      };

      builder = new Builder({
        setupBroccoliBuilder: function() { },
        trapSignals:          function() { },
        cleanupOnExit:        function() { },
        builder: {
          build: function() { return Promise.resolve(buildResults); }
        },
        processBuildResult: function(buildResults) { return Promise.resolve(buildResults); },
        project: {
          addons: [addon]
        }
      });

      buildResults = 'build results';
    });

    it('allows addons to add promises preBuild', function() {
      var preBuild = stub(addon, 'preBuild');

      return builder.build().then(function() {
        assert.equal(preBuild.called, 1, 'expected preBuild to be called');
        assert.equal(preBuild.calledWith[0][0], buildResults, 'expected preBuild to be called with the results');
      });
    });

    it('allows addons to add promises postBuild', function() {
      var postBuild = stub(addon, 'postBuild');

      return builder.build().then(function() {
        assert.equal(postBuild.called, 1, 'expected postBuild to be called');
        assert.equal(postBuild.calledWith[0][0], buildResults, 'expected postBuild to be called with the results');
      });
    });
  });
});
<|endoftext|>


<commit_before>describe( "thisissoon.core", function() {

    var runBlocks, rootScope, _cacheService, _resizeService;

    beforeEach( function() {
        var myModule = angular.module( "thisissoon.core" );

        runBlocks = myModule._runBlocks;
        myModule._runBlocks = [];

        module( "thisissoon.core" );
    });

    afterEach( function() {
        angular.module( "thisissoon.core" )._runBlocks = runBlocks;
    });

    describe( "when loaded", function() {

        beforeEach( inject( function( $rootScope, $injector ) {

            rootScope = $rootScope;

            _cacheService = $injector.get("CacheService");
            spyOn(_cacheService, "put");

            _resizeService = $injector.get("ResizeService");
            _resizeService.add = function(id, fn){
                fn.apply(this, [{}, { width: 1000, height: 200 }]);
            };
            spyOn(_resizeService, "add");

            for( var i = 0; i < runBlocks.length; ++i ) {
                $injector.invoke( runBlocks[i] );
            }
        }));

        afterEach(function(){

        });

        it("should set variables on rootScope", function(){

            expect(rootScope.cache).toEqual(_cacheService);
            expect(rootScope.env).toEqual(jasmine.any(Object));

        });

        it("should set view defaults in cache", function(){

            expect(_cacheService.put.calls.argsFor(0)).toEqual([ "navOpen", false ]);
            expect(_cacheService.put.calls.argsFor(1)).toEqual([ "loading", true ]);
            expect(_cacheService.put.calls.argsFor(2)).toEqual([ "projectList", false ]);

        });

        it("should set loading true on routeChangeStart", function(){

            rootScope.$broadcast("$routeChangeStart");

            expect(_cacheService.put.calls.argsFor(0)).toEqual([ "navOpen", false ]);
            expect(_cacheService.put.calls.argsFor(1)).toEqual([ "loading", true ]);

        });

        it("should set loading false on routeChangeSuccess", function(){

            _cacheService.put.calls.reset();
            rootScope.$broadcast("$routeChangeSuccess");

            expect(_cacheService.put.calls.argsFor(0)).toEqual([ "loading", false ]);

        });

        it("should call snSkrollr when window is correct size", function(){

            _cacheService.put.calls.reset();
            rootScope.$broadcast("$routeChangeSuccess");

            expect(_cacheService.put.calls.argsFor(0)).toEqual([ "loading", false ]);

        });

    });

});
<commit_msg>fix thisissoon-core/app.js tests<commit_after>describe( "thisissoon.core", function() {

    var runBlocks, rootScope, _cacheService, _resizeService, _window, _snSkrollr;

    beforeEach( function() {
        var myModule = angular.module( "thisissoon.core" );

        runBlocks = myModule._runBlocks;
        myModule._runBlocks = [];

        module( "thisissoon.core" );
    });

    afterEach( function() {
        angular.module( "thisissoon.core" )._runBlocks = runBlocks;
    });

    describe( "when loaded", function() {

        beforeEach( inject( function( $rootScope, $injector ) {

            rootScope = $rootScope;

            _cacheService = $injector.get("CacheService");
            spyOn(_cacheService, "put");

            _resizeService = $injector.get("ResizeService");
            _resizeService.add = function(id, fn){
                fn.apply(this, [{}, { width: 1025, height: 200 }]);
            };
            spyOn(_resizeService, "add");

            _window = $injector.get("$window");
            _window.innerWidth = 1025;

            _snSkrollr = $injector.get("snSkrollr");
            spyOn(_snSkrollr, "init");
            spyOn(_snSkrollr, "destroy");

            for( var i = 0; i < runBlocks.length; ++i ) {
                $injector.invoke( runBlocks[i] );
            }
        }));

        afterEach(function(){

        });

        it("should set variables on rootScope", function(){

            expect(rootScope.cache).toEqual(_cacheService);
            expect(rootScope.env).toEqual(jasmine.any(Object));

        });

        it("should set view defaults in cache", function(){

            expect(_cacheService.put.calls.argsFor(0)).toEqual([ "navOpen", false ]);
            expect(_cacheService.put.calls.argsFor(1)).toEqual([ "loading", true ]);
            expect(_cacheService.put.calls.argsFor(2)).toEqual([ "projectList", false ]);

        });

        it("should set loading true on routeChangeStart", function(){

            rootScope.$broadcast("$routeChangeStart");

            expect(_cacheService.put.calls.argsFor(0)).toEqual([ "navOpen", false ]);
            expect(_cacheService.put.calls.argsFor(1)).toEqual([ "loading", true ]);

        });

        it("should set loading false on routeChangeSuccess", function(){

            _cacheService.put.calls.reset();
            rootScope.$broadcast("$routeChangeSuccess");

            expect(_cacheService.put.calls.argsFor(0)).toEqual([ "loading", false ]);

        });

        it("should call snSkrollr.destroy on routeChangeStart", function(){

            rootScope.skrollrInitialised = true;
            rootScope.$broadcast("$routeChangeStart");

            expect(_snSkrollr.destroy).toHaveBeenCalled();

        });

        it("should call snSkrollr.init on routeChangeSuccess if window size is greater than 1024", function(){

            _cacheService.put.calls.reset();
            _window.innerWidth = 1025;
            rootScope.$broadcast("$routeChangeSuccess");

            expect(_snSkrollr.init).toHaveBeenCalled();

        });

    });

});
<|endoftext|>


<commit_before>import React, { Component } from 'react'
import { View, Image, TouchableOpacity } from 'react-native'
import TimeAgo from 'react-native-timeago'
import {
  Body, Left, Right,
  Card, CardItem,
  ListItem, Thumbnail,
  Button, Icon, Text
} from 'native-base'
import {Avatar} from 'react-native-material-ui'

import variables from '../../theme/variables/platform'

export default class TaskItem extends Component {
  render = () => {
    let { task, navigation } = this.props
    return (
      <TouchableOpacity activeOpacity={0.8} onPress={() => navigation.navigate('TaskDetail', task)}>
      <ListItem thumbnail>
        <Left>
          <View style={{ height: 45, width: 50 }}>
            <Image style={{ height: 45, width: 50 }} resizeMethod="resize" source={require('../../Fetch.png')} />
          </View>
        </Left>
        <Body style={{ paddingVertical: 5 }}>
          <Text>{task.objective}</Text>
          <Text note><Icon style={{ fontSize: 13 }} name="cash" /> ${task.tip} tips</Text>
          <Text note><Icon style={{ fontSize: 13 }} name="stopwatch" />{task.deadline}</Text>

          <TouchableOpacity activeOpacity={0.8} onPress={() => navigation.navigate('Profile', { user: { userID: task.userID, userAlias: task.userAlias } })}>
          <View style={{ flexDirection: 'row', flex: 1, marginVertical: 2 }}>
            <View style={{ flexDirection: 'row', flex: 1 }}>
              <Text>{task.userAlias}</Text>
              <View style={{ flexDirection: 'row', flex: 1, alignSelf: 'flex-end', marginBottom: 2 }}>
                {[, ...Array(5)].map((x, index) => (
                  <Icon name="ios-star" style={{ fontSize: 15, color: 'orange' }} key={index}/>
                ))}
              </View>
            </View>

          </View>
          </TouchableOpacity>

        </Body>
        <Right style={{ paddingVertical: 0 }}>
          {
            task.status !== 'MEETUP'
            ? <Button transparent block onPress={() => navigation.navigate('ChatRoom', { receiver: { userID: task.userID, userAlias: task.userAlias, role: 'Requester' }, objective: task.objective })}>
              <Text style={{ fontSize: 18, color: variables.brandPrimary}}>Fetch!</Text>
            </Button>
            : <Button transparent block onPress={() => navigation.navigate('ChatRoom', { receiver: { userID: task.userID, userAlias: task.userAlias, role: 'Requester' }, objective: task.objective })}>
              <Text>{task.status}</Text>
            </Button>
          }
        </Right>
      </ListItem>
      </TouchableOpacity>
    )
  }
}
<commit_msg>fix untouchable list item<commit_after>import React, { Component } from 'react'
import { View, Image, TouchableOpacity } from 'react-native'
import TimeAgo from 'react-native-timeago'
import {
  Body, Left, Right,
  Card, CardItem,
  ListItem, Thumbnail,
  Button, Icon, Text
} from 'native-base'
import {Avatar} from 'react-native-material-ui'

import variables from '../../theme/variables/platform'

export default class TaskItem extends Component {
  render = () => {
    let { task, navigation } = this.props
    return (
      <ListItem onPress={() => navigation.navigate('TaskDetail', task)} thumbnail>
        <Left>
          <View style={{ height: 45, width: 50 }}>
            <Image style={{ height: 45, width: 50 }} resizeMethod="resize" source={require('../../Fetch.png')} />
          </View>
        </Left>
        <Body style={{ paddingVertical: 5 }}>
          <Text>{task.objective}</Text>
          <Text note><Icon style={{ fontSize: 13 }} name="cash" /> ${task.tip} tips</Text>
          <Text note><Icon style={{ fontSize: 13 }} name="stopwatch" />{task.deadline}</Text>

          <TouchableOpacity activeOpacity={0.8} onPress={() => navigation.navigate('Profile', { user: { userID: task.userID, userAlias: task.userAlias } })}>
          <View style={{ flexDirection: 'row', flex: 1, marginVertical: 2 }}>
            <View style={{ flexDirection: 'row', flex: 1 }}>
              <Text>{task.userAlias}</Text>
              <View style={{ flexDirection: 'row', flex: 1, alignSelf: 'flex-end', marginBottom: 2 }}>
                {[, ...Array(5)].map((x, index) => (
                  <Icon name="ios-star" style={{ fontSize: 15, color: 'orange' }} key={index}/>
                ))}
              </View>
            </View>

          </View>
          </TouchableOpacity>

        </Body>
        <Right style={{ paddingVertical: 0 }}>
          {
            task.status !== 'MEETUP'
            ? <Button transparent block onPress={() => navigation.navigate('ChatRoom', { receiver: { userID: task.userID, userAlias: task.userAlias, role: 'Requester' }, objective: task.objective })}>
              <Text style={{ fontSize: 18, color: variables.brandPrimary}}>Fetch!</Text>
            </Button>
            : <Button transparent block onPress={() => navigation.navigate('ChatRoom', { receiver: { userID: task.userID, userAlias: task.userAlias, role: 'Requester' }, objective: task.objective })}>
              <Text>{task.status}</Text>
            </Button>
          }
        </Right>
      </ListItem>
    )
  }
}
<|endoftext|>


<commit_before>Ext4.define('Kwf.Ext4.Controller.Binding.EditWindow', {
    mixins: {
        observable: 'Ext.util.Observable'
    },
    uses: [ 'Kwf.Ext4.Data.StoreSyncQueue' ],
    focusOnEditSelector: 'field',
    form: null,
    editWindow: null,
    bindable: null,

    constructor: function(config) {
        this.mixins.observable.constructor.call(this, config);
        this.init();
    },

    init: function()
    {
        if (!this.editWindow) Ext4.Error.raise('editWindow config is required');
        if (!this.editWindow instanceof Ext4.window.Window) Ext4.Error.raise('editWindow config needs to be a Ext.window.Window');

        if (!this.saveButton) this.saveButton = this.editWindow.down('> toolbar > button#save');
        if (this.saveButton && !this.saveButton instanceof Ext4.button.Button) Ext4.Error.raise('saveButton config needs to be a Ext.button.Button');

        if (!this.deleteButton) this.deleteButton = this.editWindow.down('> toolbar > button#delete');
        if (this.deleteButton && !this.deleteButton instanceof Ext4.button.Button) Ext4.Error.raise('deleteButton config needs to be a Ext.button.Button');

        if (!this.cancelButton) this.cancelButton = this.editWindow.down('> toolbar > button#cancel');
        if (this.cancelButton && !this.cancelButton instanceof Ext4.button.Button) Ext4.Error.raise('cancelButton config needs to be a Ext.button.Button');

        if (!this.bindable) Ext4.Error.raise('bindable config is required');
        if (!this.bindable instanceof Ext4.window.Window) Ext4.Error.raise('bindable config needs to be a Kwf.Ext4.Controller.Bindable.Abstract');

        if (!this.form) {
            this.form = this.editWindow.down('form');
        }
        if (!this.form) Ext4.Error.raise('form config is required');
        if (!this.form instanceof Ext4.form.Panel) Ext4.Error.raise('form config needs to be a Ext.form.Panel');

        if (this.saveButton) {
            this.saveButton.on('click', function() {
                if (this.doSave() !== false) {
                    this.closeWindow();
                }
            }, this);
        }

        if (this.cancelButton) {
            this.cancelButton.on('click', this.onCancel, this);
        }
        this.editWindow.on('beforeclose', function() {
            this.onCancel();
            return false;
        }, this);
    },

    //store is optional, used for sync
    openEditWindow: function(row, store)
    {
        this._loadedStore = store;
        this.bindable.load(row);
        if (row.phantom) {
            this.editWindow.setTitle(trlKwf('Add'));
        } else {
            this.editWindow.setTitle(trlKwf('Edit'));
        }
        this.editWindow.show();
        if (this.focusOnEditSelector) {
            this.editWindow.down(this.focusOnEditSelector).focus();
        }
    },

    validateAndSubmit: function(options)
    {
        return this.bindable.validateAndSubmit(options);
    },

    doSave: function()
    {
        if (!this.bindable.isValid()) {
            Ext4.Msg.alert(trlKwf('Save'),
                trlKwf("Can't save, please fill all red underlined fields correctly."));
            return false;
        }

        var row = this.bindable.getLoadedRecord();
        if (row.phantom && this._loadedStore
            && this._loadedStore.indexOf(row) == -1
        ) {
            this._loadedStore.add(row);
        }

        if (this.autoSync) {
            var syncQueue = new Kwf.Ext4.Data.StoreSyncQueue();
            if (this._loadedStore) {
                syncQueue.add(this._loadedStore); //sync store first
            }
            this.bindable.save(syncQueue);    //then bindables (so bindable grid is synced second)
                                              //bindable forms can still update the row as the sync is not yet started
            syncQueue.start({
                success: function() {
                    this.fireEvent('savesuccess');
                },
                scope: this
            });
        } else {
            this.bindable.save();
        }
        this.fireEvent('save');

        return true;
    },

    onCancel: function()
    {
        if (this.bindable.isDirty()) {
            Ext4.Msg.show({
                title: trl('Speichern'),
                msg: trl('Wollen Sie die Änderungen speichern?'),
                icon: Ext4.MessageBox.QUESTION,
                buttons: Ext4.Msg.YESNOCANCEL,
                fn: function(btn) {
                    if (btn == 'no') {
                        this.closeWindow();
                    } else if (btn == 'yes') {
                        if (this.doSave() !== false) {
                            this.closeWindow();
                        }
                    }
                },
                scope: this
            });
        } else {
            this.closeWindow();
        }
    },

    closeWindow: function()
    {
        this.bindable.reset();
        this.editWindow.hide();
    }

});
<commit_msg>AutoSync also saves record if no store set<commit_after>Ext4.define('Kwf.Ext4.Controller.Binding.EditWindow', {
    mixins: {
        observable: 'Ext.util.Observable'
    },
    uses: [ 'Kwf.Ext4.Data.StoreSyncQueue' ],
    focusOnEditSelector: 'field',
    form: null,
    editWindow: null,
    bindable: null,

    constructor: function(config) {
        this.mixins.observable.constructor.call(this, config);
        this.init();
    },

    init: function()
    {
        if (!this.editWindow) Ext4.Error.raise('editWindow config is required');
        if (!this.editWindow instanceof Ext4.window.Window) Ext4.Error.raise('editWindow config needs to be a Ext.window.Window');

        if (!this.saveButton) this.saveButton = this.editWindow.down('> toolbar > button#save');
        if (this.saveButton && !this.saveButton instanceof Ext4.button.Button) Ext4.Error.raise('saveButton config needs to be a Ext.button.Button');

        if (!this.deleteButton) this.deleteButton = this.editWindow.down('> toolbar > button#delete');
        if (this.deleteButton && !this.deleteButton instanceof Ext4.button.Button) Ext4.Error.raise('deleteButton config needs to be a Ext.button.Button');

        if (!this.cancelButton) this.cancelButton = this.editWindow.down('> toolbar > button#cancel');
        if (this.cancelButton && !this.cancelButton instanceof Ext4.button.Button) Ext4.Error.raise('cancelButton config needs to be a Ext.button.Button');

        if (!this.bindable) Ext4.Error.raise('bindable config is required');
        if (!this.bindable instanceof Ext4.window.Window) Ext4.Error.raise('bindable config needs to be a Kwf.Ext4.Controller.Bindable.Abstract');

        if (!this.form) {
            this.form = this.editWindow.down('form');
        }
        if (!this.form) Ext4.Error.raise('form config is required');
        if (!this.form instanceof Ext4.form.Panel) Ext4.Error.raise('form config needs to be a Ext.form.Panel');

        if (this.saveButton) {
            this.saveButton.on('click', function() {
                if (this.doSave() !== false) {
                    this.closeWindow();
                }
            }, this);
        }

        if (this.cancelButton) {
            this.cancelButton.on('click', this.onCancel, this);
        }
        this.editWindow.on('beforeclose', function() {
            this.onCancel();
            return false;
        }, this);
    },

    //store is optional, used for sync
    openEditWindow: function(row, store)
    {
        this._loadedStore = store;
        this.bindable.load(row);
        if (row.phantom) {
            this.editWindow.setTitle(trlKwf('Add'));
        } else {
            this.editWindow.setTitle(trlKwf('Edit'));
        }
        this.editWindow.show();
        if (this.focusOnEditSelector) {
            this.editWindow.down(this.focusOnEditSelector).focus();
        }
    },

    validateAndSubmit: function(options)
    {
        return this.bindable.validateAndSubmit(options);
    },

    doSave: function()
    {
        if (!this.bindable.isValid()) {
            Ext4.Msg.alert(trlKwf('Save'),
                trlKwf("Can't save, please fill all red underlined fields correctly."));
            return false;
        }

        var row = this.bindable.getLoadedRecord();
        if (row.phantom && this._loadedStore
            && this._loadedStore.indexOf(row) == -1
        ) {
            this._loadedStore.add(row);
        }

        if (this.autoSync) {
            if (this._loadedStore) {
                var syncQueue = new Kwf.Ext4.Data.StoreSyncQueue();
                syncQueue.add(this._loadedStore); //sync store first
                this.bindable.save(syncQueue);    //then bindables (so bindable grid is synced second)
                                                  //bindable forms can still update the row as the sync is not yet started
                syncQueue.start({
                    success: function() {
                        this.fireEvent('savesuccess');
                    },
                    scope: this
                });
            } else {
                this.bindable.save();
                this.bindable.getLoadedRecord().save({
                    callback: function(records, operation, success) {
                        if (success) this.fireEvent('savesuccess');
                    },
                    scope: this
                });
            }
        } else {
            this.bindable.save();
        }
        this.fireEvent('save');

        return true;
    },

    onCancel: function()
    {
        if (this.bindable.isDirty()) {
            Ext4.Msg.show({
                title: trl('Speichern'),
                msg: trl('Wollen Sie die Änderungen speichern?'),
                icon: Ext4.MessageBox.QUESTION,
                buttons: Ext4.Msg.YESNOCANCEL,
                fn: function(btn) {
                    if (btn == 'no') {
                        this.closeWindow();
                    } else if (btn == 'yes') {
                        if (this.doSave() !== false) {
                            this.closeWindow();
                        }
                    }
                },
                scope: this
            });
        } else {
            this.closeWindow();
        }
    },

    closeWindow: function()
    {
        this.bindable.reset();
        this.editWindow.hide();
    }

});
<|endoftext|>


<commit_before>/*
 * This program is part of the OpenLMIS logistics management information system platform software.
 * Copyright © 2017 VillageReach
 *
 * This program is free software: you can redistribute it and/or modify it under the terms
 * of the GNU Affero General Public License as published by the Free Software Foundation, either
 * version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Affero General Public License for more details. You should have received a copy of
 * the GNU Affero General Public License along with this program. If not, see
 * http://www.gnu.org/licenses.  For additional information contact info@OpenLMIS.org.
 */

(function() {

    'use strict';

    /**
     * @ngdoc controller
     * @name requisition-batch-approval.controller:RequisitionBatchApprovalController
     *
     * @description
     * Controller for approval list of requisitions.
     */

    angular
        .module('requisition-batch-approval')
        .controller('RequisitionBatchApprovalController', controller);

    controller.$inject = [
        '$stateParams', 'calculationFactory', 'stateTrackerService', 'loadingModalService', 'messageService',
            'alertService', 'confirmService', 'notificationService', 'requisitionBatchSaveFactory',
            'requisitionBatchApproveFactory', 'offlineService', 'RequisitionWatcher', '$scope',
            'requisitionService', '$q'
    ];

    function controller($stateParams, calculationFactory, stateTrackerService, loadingModalService,
                        messageService, alertService, confirmService, notificationService, requisitionBatchSaveFactory,
                        requisitionBatchApproveFactory, offlineService, RequisitionWatcher, $scope, requisitionService,
                        $q) {

        var vm = this;

        vm.$onInit = onInit;
        vm.updateLineItem = updateLineItem;
        vm.revert = revert;
        vm.sync = sync;
        vm.approve = approve;
        vm.isOffline = offlineService.isOffline;

        /**
         * @ngdoc property
         * @propertyOf requisition-batch-approval.controller:RequisitionBatchApprovalController
         * @name requisitions
         * @type {Array}
         *
         * @description
         * Holds requisitions that can be approved on the view.
         */
        vm.requisitions = undefined;

        /**
         * @ngdoc property
         * @propertyOf requisition-batch-approval.controller:RequisitionBatchApprovalController
         * @name errors
         * @type {Array}
         *
         * @description
         * Keeps a list of all current errors on the view.
         */
        vm.errors = [];

        /**
         * @ngdoc property
         * @propertyOf requisition-batch-approval.controller:RequisitionBatchApprovalController
         * @name products
         * @type {Array}
         *
         * @description
         * Holds all products that should be displayed as rows in table. Each product from array contains its code and name,
         * information about total cost and quantity of product for all facilities,
         * and array of ids of requisitions that contain line item of this product.
         */
        vm.products = undefined;

        /**
         * @ngdoc property
         * @propertyOf requisition-batch-approval.controller:RequisitionBatchApprovalController
         * @name lineItems
         * @type {Array}
         *
         * @description
         * Holds all line items from all requisitions - each line item is identified by requisition id and product id.
         */
        vm.lineItems = undefined;

        /**
         * @ngdoc property
         * @propertyOf requisition-batch-approval.controller:RequisitionBatchApprovalController
         * @name totalCost
         * @type {Number}
         *
         * @description
         * Holds total cost of all products from all requisitions.
         */
        vm.totalCost = undefined;

        /**
         * @ngdoc property
         * @propertyOf requisition-batch-approval.controller:RequisitionBatchApprovalController
         * @name requisitionsCopy
         * @type {Array}
         *
         * @description
         * Holds copy of original requisitions that can be approved on the view.
         * It is used to provide 'revert' functionality.
         */
        vm.requisitionsCopy = undefined;

        /**
         * @ngdoc method
         * @methodOf requisition-batch-approval.controller:RequisitionBatchApprovalController
         * @name $onInit
         *
         * @description
         * Initialization method called after the controller has been created. Responsible for
         * setting data to be available on the view.
         */
        function onInit() {
            loadingModalService.open();
            var promises = [];

            angular.forEach($stateParams.requisitions, function (requisition) {
                promises.push(requisitionService.get(requisition.id));
            });

            $q.all(promises).then(function(requisitions) {
                prepareDataToDisplay(requisitions);
            }).finally(loadingModalService.close);
        }

        function prepareDataToDisplay(requisitions) {
            vm.totalCost = 0;
            vm.requisitions = [];

            vm.products = {};
            vm.lineItems = [];

            angular.forEach(requisitions, function(requisition) {
                calculateRequisitionTotalCost(requisition);
                new RequisitionWatcher($scope, requisition);
                vm.requisitions.push(requisition);

                vm.lineItems[requisition.id] = [];
                angular.forEach(requisition.requisitionLineItems, function(lineItem) {
                    if (!(lineItem.skipped)) {
                        vm.totalCost += lineItem.totalCost;
                        vm.lineItems[requisition.id][lineItem.orderable.id] = lineItem;

                        if (vm.products[lineItem.orderable.id] !== undefined) {
                            vm.products[lineItem.orderable.id].requisitions.push(requisition.id);
                            vm.products[lineItem.orderable.id].totalCost += lineItem.totalCost;
                            vm.products[lineItem.orderable.id].totalQuantity += lineItem.approvedQuantity;
                        } else {
                            vm.products[lineItem.orderable.id] = {
                                code: lineItem.orderable.productCode,
                                name: lineItem.orderable.fullProductName,
                                totalCost: lineItem.totalCost,
                                totalQuantity: lineItem.approvedQuantity,
                                requisitions: [requisition.id]
                            };
                        }
                    }
                });
            });

            vm.requisitionsCopy = angular.copy(vm.requisitions);
        }

        /**
         * @ngdoc method
         * @methodOf requisition-batch-approval.controller:RequisitionBatchApprovalController
         * @name updateLineItem
         *
         * @description
         * Updates cost of line item, total cost of each product for all facilities
         * and total cost of all products for all facilities.
         */
        function updateLineItem(lineItem, requisition) {
            lineItem.totalCost = calculationFactory['totalCost'](lineItem, requisition);
            updateTotalValues(lineItem.orderable.id);
            calculateRequisitionTotalCost(requisition);
        }

        /**
         * @ngdoc method
         * @methodOf requisition-batch-approval.controller:RequisitionBatchApprovalController
         * @name revert
         *
         * @description
         * Replaces all values manually entered by user with the values the page displayed when originally loaded.
         */
        function revert() {
            confirmService.confirm('requisitionBatchApproval.revertConfirm', 'requisitionBatchApproval.revert').then(function() {
                prepareDataToDisplay(vm.requisitionsCopy);
            });

        }

        /**
         * @ngdoc method
         * @methodOf requisition-batch-approval.controller:RequisitionBatchApprovalController
         * @name sync
         *
         * @description
         * Responsible for syncing requisitions with the server. If the any of the requisitions fails to sync,
         * an error notification will be displayed. Otherwise, a success notification will be shown.
         */
        function sync() {
            //todo
        }

        /**
         * @ngdoc method
         * @methodOf requisition-batch-approval.controller:RequisitionBatchApprovalController
         * @name approve
         *
         * @description
         * Approves all displayed requisitions.
         */
        function approve() {
            var errors = [],
                successfulRequisitions = [],
                erroredRequisitions = [];

            loadingModalService.open();

            vm.requisitions.forEach(function(requisition){
                if(requisitionValidator.validateRequisition(requisition)){
                    successfulRequisitions.push(requisition);
                } else {
                    erroredRequisitions.push(requisition);
                    errors.push({
                        requisitionId: requisition.id,
                        error: {
                            messageKey: "requisitionBatchApproval.invalidRequisition",
                            message: messageService.get("requisitionBatchApproval.invalidRequisition")
                        }
                    })
                }
            });

            requisitionBatchSaveFactory(successfulRequisitions)
            .catch(manageErrors)
            .then(function(){
                return requisitionBatchApproveFactory(successfulRequisitions);
            })
            .catch(manageErrors)
            .finally(function(){
                loadingModalService.close();

                vm.requisitions = erroredRequisitions; // updating the list of requisitions

                if(errors.length > 0){
                    // Display error messages....
                    var errorTitle = messageService.get("requisitionBatchApproval.approvalError", {
                        errorCount: errors.length
                    });
                    alertService.error(errorTitle);
                } else {
                    var successMessage = messageService.get("requisitionBatchApproval.approvalSuccess", {
                        successCount: successfulRequisitions.length
                    });
                    notificationService.success(successMessage);
                    stateTrackerService.goToPreviousState('openlmis.requisitions.approvalList');
                }
            });

            function manageErrors(newErrors){
                // add errors to total errors
                errors = errors.concat(newErrors);

                var errorIds = [];
                errors.forEach(function(error){
                    errorIds.push(error.requisitionId);
                });

                // Rebuild success/error arrays
                successfulRequisitions = [];
                erroredRequisitions = [];

                vm.requisitions.forEach(function(requisition){
                    if(errorIds.indexOf(requisition.id) >= 0) {
                        erroredRequisitions.push(requisition);
                    } else {
                        successfulRequisitions.push(requisition);
                    }
                });
            }
        }

        /**
         * @ngdoc method
         * @methodOf requisition-batch-approval.controller:RequisitionBatchApprovalController
         * @name requisitionHasErrors
         *
         * @param {Object} requisition Requisition object
         *
         * @return {Boolean} If the requisition has errors
         *
         * @description
         * Approves all displayed requisitions.
         */
        function requisitionHasErrors(requisition) {
            var errors = [];
            vm.errors.forEach(function(error){
                if(requisition.id === error.requisitionId){
                    errors.push(error);
                }
            });

            if(errors.length > 0) {
                return true;
            } else {
                return false;
            }

        }

        function calculateRequisitionTotalCost(requisition) {
            requisition.$totalCost = 0;
            angular.forEach(requisition.requisitionLineItems, function(lineItem) {
                requisition.$totalCost += lineItem.totalCost;
            });
        }

        function updateTotalValues(productId) {
            vm.products[productId].totalCost = 0;
            vm.products[productId].totalQuantity = 0;
            vm.totalCost = 0;

            angular.forEach(vm.requisitions, function(requisition) {
                angular.forEach(requisition.requisitionLineItems, function(lineItem) {
                    vm.totalCost += lineItem.totalCost;
                    if (lineItem.orderable.id === productId) {
                        vm.products[productId].totalCost += lineItem.totalCost;
                        vm.products[productId].totalQuantity += lineItem.approvedQuantity;
                    }
                });
            });
        }

        function saveToStorage(requisition) {
            requisition.$modified = false;
            requisition.$availableOffline = true;
            offlineRequisitions.put(requisition);
        }
    }

})();
<commit_msg>MW-86: Removed requisition validator<commit_after>/*
 * This program is part of the OpenLMIS logistics management information system platform software.
 * Copyright © 2017 VillageReach
 *
 * This program is free software: you can redistribute it and/or modify it under the terms
 * of the GNU Affero General Public License as published by the Free Software Foundation, either
 * version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Affero General Public License for more details. You should have received a copy of
 * the GNU Affero General Public License along with this program. If not, see
 * http://www.gnu.org/licenses.  For additional information contact info@OpenLMIS.org.
 */

(function() {

    'use strict';

    /**
     * @ngdoc controller
     * @name requisition-batch-approval.controller:RequisitionBatchApprovalController
     *
     * @description
     * Controller for approval list of requisitions.
     */

    angular
        .module('requisition-batch-approval')
        .controller('RequisitionBatchApprovalController', controller);

    controller.$inject = [
        '$stateParams', 'calculationFactory', 'stateTrackerService', 'loadingModalService', 'messageService',
            'alertService', 'confirmService', 'notificationService', 'requisitionBatchSaveFactory',
            'requisitionBatchApproveFactory', 'offlineService', 'RequisitionWatcher', '$scope',
            'requisitionService', '$q'
    ];

    function controller($stateParams, calculationFactory, stateTrackerService, loadingModalService,
                        messageService, alertService, confirmService, notificationService, requisitionBatchSaveFactory,
                        requisitionBatchApproveFactory, offlineService, RequisitionWatcher, $scope, requisitionService,
                        $q) {

        var vm = this;

        vm.$onInit = onInit;
        vm.updateLineItem = updateLineItem;
        vm.revert = revert;
        vm.sync = sync;
        vm.approve = approve;
        vm.isOffline = offlineService.isOffline;

        /**
         * @ngdoc property
         * @propertyOf requisition-batch-approval.controller:RequisitionBatchApprovalController
         * @name requisitions
         * @type {Array}
         *
         * @description
         * Holds requisitions that can be approved on the view.
         */
        vm.requisitions = undefined;

        /**
         * @ngdoc property
         * @propertyOf requisition-batch-approval.controller:RequisitionBatchApprovalController
         * @name errors
         * @type {Array}
         *
         * @description
         * Keeps a list of all current errors on the view.
         */
        vm.errors = [];

        /**
         * @ngdoc property
         * @propertyOf requisition-batch-approval.controller:RequisitionBatchApprovalController
         * @name products
         * @type {Array}
         *
         * @description
         * Holds all products that should be displayed as rows in table. Each product from array contains its code and name,
         * information about total cost and quantity of product for all facilities,
         * and array of ids of requisitions that contain line item of this product.
         */
        vm.products = undefined;

        /**
         * @ngdoc property
         * @propertyOf requisition-batch-approval.controller:RequisitionBatchApprovalController
         * @name lineItems
         * @type {Array}
         *
         * @description
         * Holds all line items from all requisitions - each line item is identified by requisition id and product id.
         */
        vm.lineItems = undefined;

        /**
         * @ngdoc property
         * @propertyOf requisition-batch-approval.controller:RequisitionBatchApprovalController
         * @name totalCost
         * @type {Number}
         *
         * @description
         * Holds total cost of all products from all requisitions.
         */
        vm.totalCost = undefined;

        /**
         * @ngdoc property
         * @propertyOf requisition-batch-approval.controller:RequisitionBatchApprovalController
         * @name requisitionsCopy
         * @type {Array}
         *
         * @description
         * Holds copy of original requisitions that can be approved on the view.
         * It is used to provide 'revert' functionality.
         */
        vm.requisitionsCopy = undefined;

        /**
         * @ngdoc method
         * @methodOf requisition-batch-approval.controller:RequisitionBatchApprovalController
         * @name $onInit
         *
         * @description
         * Initialization method called after the controller has been created. Responsible for
         * setting data to be available on the view.
         */
        function onInit() {
            loadingModalService.open();
            var promises = [];

            angular.forEach($stateParams.requisitions, function (requisition) {
                promises.push(requisitionService.get(requisition.id));
            });

            $q.all(promises).then(function(requisitions) {
                prepareDataToDisplay(requisitions);
            }).finally(loadingModalService.close);
        }

        function prepareDataToDisplay(requisitions) {
            vm.totalCost = 0;
            vm.requisitions = [];

            vm.products = {};
            vm.lineItems = [];

            angular.forEach(requisitions, function(requisition) {
                calculateRequisitionTotalCost(requisition);
                new RequisitionWatcher($scope, requisition);
                vm.requisitions.push(requisition);

                vm.lineItems[requisition.id] = [];
                angular.forEach(requisition.requisitionLineItems, function(lineItem) {
                    if (!(lineItem.skipped)) {
                        vm.totalCost += lineItem.totalCost;
                        vm.lineItems[requisition.id][lineItem.orderable.id] = lineItem;

                        if (vm.products[lineItem.orderable.id] !== undefined) {
                            vm.products[lineItem.orderable.id].requisitions.push(requisition.id);
                            vm.products[lineItem.orderable.id].totalCost += lineItem.totalCost;
                            vm.products[lineItem.orderable.id].totalQuantity += lineItem.approvedQuantity;
                        } else {
                            vm.products[lineItem.orderable.id] = {
                                code: lineItem.orderable.productCode,
                                name: lineItem.orderable.fullProductName,
                                totalCost: lineItem.totalCost,
                                totalQuantity: lineItem.approvedQuantity,
                                requisitions: [requisition.id]
                            };
                        }
                    }
                });
            });

            vm.requisitionsCopy = angular.copy(vm.requisitions);
        }

        /**
         * @ngdoc method
         * @methodOf requisition-batch-approval.controller:RequisitionBatchApprovalController
         * @name updateLineItem
         *
         * @description
         * Updates cost of line item, total cost of each product for all facilities
         * and total cost of all products for all facilities.
         */
        function updateLineItem(lineItem, requisition) {
            lineItem.totalCost = calculationFactory['totalCost'](lineItem, requisition);
            updateTotalValues(lineItem.orderable.id);
            calculateRequisitionTotalCost(requisition);
        }

        /**
         * @ngdoc method
         * @methodOf requisition-batch-approval.controller:RequisitionBatchApprovalController
         * @name revert
         *
         * @description
         * Replaces all values manually entered by user with the values the page displayed when originally loaded.
         */
        function revert() {
            confirmService.confirm('requisitionBatchApproval.revertConfirm', 'requisitionBatchApproval.revert').then(function() {
                prepareDataToDisplay(vm.requisitionsCopy);
            });

        }

        /**
         * @ngdoc method
         * @methodOf requisition-batch-approval.controller:RequisitionBatchApprovalController
         * @name sync
         *
         * @description
         * Responsible for syncing requisitions with the server. If the any of the requisitions fails to sync,
         * an error notification will be displayed. Otherwise, a success notification will be shown.
         */
        function sync() {
            //todo
        }

        /**
         * @ngdoc method
         * @methodOf requisition-batch-approval.controller:RequisitionBatchApprovalController
         * @name approve
         *
         * @description
         * Approves all displayed requisitions.
         */
        function approve() {
            var errors = [],
                // successfulRequisitions will change, don't want to accidentally change original array
                successfulRequisitions = vm.requisitions.slice(),
                erroredRequisitions = [];

            loadingModalService.open();

            requisitionBatchSaveFactory(successfulRequisitions)
            .catch(manageErrors)
            .then(function(){
                return requisitionBatchApproveFactory(successfulRequisitions);
            })
            .catch(manageErrors)
            .finally(function(){
                loadingModalService.close();

                vm.requisitions = erroredRequisitions; // updating the list of requisitions

                if(errors.length > 0){
                    // Display error messages....
                    var errorTitle = messageService.get("requisitionBatchApproval.approvalError", {
                        errorCount: errors.length
                    });
                    alertService.error(errorTitle);
                } else {
                    var successMessage = messageService.get("requisitionBatchApproval.approvalSuccess", {
                        successCount: successfulRequisitions.length
                    });
                    notificationService.success(successMessage);
                    stateTrackerService.goToPreviousState('openlmis.requisitions.approvalList');
                }
            });

            function manageErrors(newErrors){
                // add errors to total errors
                errors = errors.concat(newErrors);

                var errorIds = [];
                errors.forEach(function(error){
                    errorIds.push(error.requisitionId);
                });

                // Rebuild success/error arrays
                successfulRequisitions = [];
                erroredRequisitions = [];

                vm.requisitions.forEach(function(requisition){
                    if(errorIds.indexOf(requisition.id) >= 0) {
                        erroredRequisitions.push(requisition);
                    } else {
                        successfulRequisitions.push(requisition);
                    }
                });
            }
        }

        /**
         * @ngdoc method
         * @methodOf requisition-batch-approval.controller:RequisitionBatchApprovalController
         * @name requisitionHasErrors
         *
         * @param {Object} requisition Requisition object
         *
         * @return {Boolean} If the requisition has errors
         *
         * @description
         * Approves all displayed requisitions.
         */
        function requisitionHasErrors(requisition) {
            var errors = [];
            vm.errors.forEach(function(error){
                if(requisition.id === error.requisitionId){
                    errors.push(error);
                }
            });

            if(errors.length > 0) {
                return true;
            } else {
                return false;
            }

        }

        function calculateRequisitionTotalCost(requisition) {
            requisition.$totalCost = 0;
            angular.forEach(requisition.requisitionLineItems, function(lineItem) {
                requisition.$totalCost += lineItem.totalCost;
            });
        }

        function updateTotalValues(productId) {
            vm.products[productId].totalCost = 0;
            vm.products[productId].totalQuantity = 0;
            vm.totalCost = 0;

            angular.forEach(vm.requisitions, function(requisition) {
                angular.forEach(requisition.requisitionLineItems, function(lineItem) {
                    vm.totalCost += lineItem.totalCost;
                    if (lineItem.orderable.id === productId) {
                        vm.products[productId].totalCost += lineItem.totalCost;
                        vm.products[productId].totalQuantity += lineItem.approvedQuantity;
                    }
                });
            });
        }

        function saveToStorage(requisition) {
            requisition.$modified = false;
            requisition.$availableOffline = true;
            offlineRequisitions.put(requisition);
        }
    }

})();
<|endoftext|>


<commit_before>document.addEventListener('DOMContentLoaded', function() {

  window.listOfErrorsForCucumberTests = []
  window.PubSub.subscribe("clientside-form-validation.invalid", function(msg, data) {
    window.listOfErrorsForCucumberTests = data.errors
  })

  window.listOfIndividualErrorsForCucumberTests = []
  window.PubSub.subscribe("clientside-form-validation.error", function(msg, data) {
    window.listOfIndividualErrorsForCucumberTests.push(data.error)
  })

});
<commit_msg>linting fixes<commit_after>document.addEventListener('DOMContentLoaded', function () {
  window.listOfErrorsForCucumberTests = []
  window.PubSub.subscribe('clientside-form-validation.invalid', function (msg, data) {
    window.listOfErrorsForCucumberTests = data.errors
  })

  window.listOfIndividualErrorsForCucumberTests = []
  window.PubSub.subscribe('clientside-form-validation.error', function (msg, data) {
    window.listOfIndividualErrorsForCucumberTests.push(data.error)
  })
})
<|endoftext|>


<commit_before>// Copyright (C) 2016 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
(function() {
  'use strict';

  Polymer({
    is: 'gr-keyboard-shortcuts-dialog',

    /**
     * Fired when the user presses the close button.
     *
     * @event close
     */

    properties: {
      view: String,
    },

    hostAttributes: {
      role: 'dialog',
    },

    _computeInView: function(currentView, view) {
      return view == currentView;
    },

    _computeInChangeListView: function(currentView) {
      return currentView == 'gr-change-list-view' ||
          currentView == 'gr-dashboard-view';
    },

    _handleCloseTap: function(e) {
      e.preventDefault();
      this.fire('close', null, {bubbles: false});
    },
  });
})();
<commit_msg>gr-keyboard-shortcuts-dialog.js: Use strict equality comparison<commit_after>// Copyright (C) 2016 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
(function() {
  'use strict';

  Polymer({
    is: 'gr-keyboard-shortcuts-dialog',

    /**
     * Fired when the user presses the close button.
     *
     * @event close
     */

    properties: {
      view: String,
    },

    hostAttributes: {
      role: 'dialog',
    },

    _computeInView: function(currentView, view) {
      return view === currentView;
    },

    _computeInChangeListView: function(currentView) {
      return currentView === 'gr-change-list-view' ||
          currentView === 'gr-dashboard-view';
    },

    _handleCloseTap: function(e) {
      e.preventDefault();
      this.fire('close', null, {bubbles: false});
    },
  });
})();
<|endoftext|>


<commit_before>import { fromJS } from 'immutable';
import reducer from '../reducer';

describe('Admin | containers | Webhooks | ListView | reducer', () => {
  const initialState = fromJS({
    webhooks: [
      {
        id: 1,
        name: 'webhook 1',
        url: 'http://localhost:5000',
        headers: {},
        events: ['entry.create', 'entry.update', 'entry.delete'],
        isEnabled: true,
      },
    ],
    webhooksToDelete: [],
    webhookToDelete: null,
  });
  it('It should update webhooks state with received data on GET_DATA_SUCCEEDED', () => {
    const state = initialState;
    const receivedData = [
      {
        id: 1,
        name: 'webhook 1',
        url: 'http://localhost:5000',
        headers: {},
        events: ['entry.create', 'entry.update', 'entry.delete'],
        isEnabled: true,
      },
      {
        id: 2,
        name: 'webhook 2',
        url: 'http://localhost:4000',
        headers: {},
        events: ['media.create', 'media.update'],
        isEnabled: false,
      },
    ];

    const action = {
      type: 'GET_DATA_SUCCEEDED',
      data: receivedData,
    };

    const expectedState = state.set('webhooks', fromJS(receivedData));

    expect(reducer(state, action)).toEqual(expectedState);
  });

  it('It should toggle webhook isEnabled state on SET_WEBHOOK_ENABLED', () => {
    const state = initialState;

    const webhookToUpdate = 1;

    const keys = [webhookToUpdate, 'isEnabled'];

    const action = {
      type: 'SET_WEBHOOK_ENABLED',
      keys: keys,
      value: false,
    };

    const expectedState = state.setIn(['webhooks', ...keys], action.value);

    expect(reducer(state, action)).toEqual(expectedState);

    //expect(true).toBe(true);
  });
});
<commit_msg>tests<commit_after>import { fromJS } from 'immutable';
import reducer from '../reducer';

describe('Admin | containers | Webhooks | ListView | reducer', () => {
  const initialState = fromJS({
    webhooks: [
      {
        id: 1,
        name: 'webhook 1',
        url: 'http://localhost:5000',
        headers: {},
        events: ['entry.create', 'entry.update', 'entry.delete'],
        isEnabled: true,
      },
    ],
    webhooksToDelete: [],
    webhookToDelete: null,
  });
  it('It should update webhooks state with received data on GET_DATA_SUCCEEDED', () => {
    const state = initialState;
    const receivedData = [
      {
        id: 1,
        name: 'webhook 1',
        url: 'http://localhost:5000',
        headers: {},
        events: ['entry.create', 'entry.update', 'entry.delete'],
        isEnabled: true,
      },
      {
        id: 2,
        name: 'webhook 2',
        url: 'http://localhost:4000',
        headers: {},
        events: ['media.create', 'media.update'],
        isEnabled: false,
      },
    ];

    const action = {
      type: 'GET_DATA_SUCCEEDED',
      data: receivedData,
    };

    const expectedState = state.set('webhooks', fromJS(receivedData));

    expect(reducer(state, action)).toEqual(expectedState);
  });

  it('It should toggle webhook isEnabled state on SET_WEBHOOK_ENABLED', () => {
    const state = initialState;

    const webhookToUpdate = 1;

    const keys = [webhookToUpdate, 'isEnabled'];

    const action = {
      type: 'SET_WEBHOOK_ENABLED',
      keys: keys,
      value: false,
    };

    const expectedState = state.setIn(['webhooks', ...keys], action.value);
    expect(reducer(state, action)).toEqual(expectedState);
  });
});
<|endoftext|>


<commit_before>/*
 *
 * HomePage
 *
 */

import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { createStructuredSelector } from 'reselect';
import { size } from 'lodash';
import Helmet from 'react-helmet';
import { makeSelectLoading, makeSelectModels } from 'containers/App/selectors';

// Design
import ContentHeader from 'components/ContentHeader';
import EmptyContentTypeView from 'components/EmptyContentTypeView';

import selectHomePage from './selectors';
import styles from './styles.scss';

export class HomePage extends React.Component { // eslint-disable-line react/prefer-stateless-function

  handleClick = () => {
    console.log(this.props.homePage);
  }

  render() {
    if (this.props.modelsLoading) return
;

    const component = size(this.props.models) === 0 ? <EmptyContentTypeView handleClick={this.handleClick} /> :
;

    return (

        <Helmet
          title="HomePage"
          meta={[
            { name: 'description', content: 'Description of HomePage' },
          ]}
        />
        <ContentHeader
          name={'home.contentTypeBuilder.name'}
          description={'home.contentTypeBuilder.description'}
          noMargin
        />
        {component}

    );
  }
}

const mapStateToProps = createStructuredSelector({
  homePage: selectHomePage(),
  modelsLoading: makeSelectLoading(),
  models: makeSelectModels(),
});

function mapDispatchToProps(dispatch) {
  return bindActionCreators(
    {},
    dispatch,
  );
};

HomePage.propTypes =  {
  homePage: React.PropTypes.object.isRequired,
  models: React.PropTypes.oneOfType([
    React.PropTypes.object,
    React.PropTypes.array,
  ]),
  modelsLoading: React.PropTypes.bool,
};

export default connect(mapStateToProps, mapDispatchToProps)(HomePage);
<commit_msg>Test npm link<commit_after>/*
 *
 * HomePage
 *
 */

import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { createStructuredSelector } from 'reselect';
import { size } from 'lodash';
import Helmet from 'react-helmet';
import { makeSelectLoading, makeSelectModels } from 'containers/App/selectors';

// Design
import ContentHeader from 'components/ContentHeader';
import EmptyContentTypeView from 'components/EmptyContentTypeView';

import selectHomePage from './selectors';
import styles from './styles.scss';

export class HomePage extends React.Component { // eslint-disable-line react/prefer-stateless-function

  handleClick = () => {
    console.log('ici', this.props.homePage);
  }

  render() {
    if (this.props.modelsLoading) return
;

    const component = size(this.props.models) === 0 ? <EmptyContentTypeView handleClick={this.handleClick} /> :
;

    return (

        <Helmet
          title="HomePage"
          meta={[
            { name: 'description', content: 'Description of HomePage' },
          ]}
        />
        <ContentHeader
          name={'home.contentTypeBuilder.name'}
          description={'home.contentTypeBuilder.description'}
          noMargin
        />
        {component}

    );
  }
}

const mapStateToProps = createStructuredSelector({
  homePage: selectHomePage(),
  modelsLoading: makeSelectLoading(),
  models: makeSelectModels(),
});

function mapDispatchToProps(dispatch) {
  return bindActionCreators(
    {},
    dispatch,
  );
};

HomePage.propTypes =  {
  homePage: React.PropTypes.object.isRequired,
  models: React.PropTypes.oneOfType([
    React.PropTypes.object,
    React.PropTypes.array,
  ]),
  modelsLoading: React.PropTypes.bool,
};

export default connect(mapStateToProps, mapDispatchToProps)(HomePage);
<|endoftext|>


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

var SetStateFromEnd = function (tween, tweenData, diff)
{
    if (tweenData.yoyo)
    {
        //  We've hit the end of a Playing Forward TweenData and we have a yoyo

        //  Account for any extra time we got from the previous frame
        tweenData.elapsed = diff;
        tweenData.progress = diff / tweenData.duration;

        if (tweenData.flipX)
        {
            tweenData.target.toggleFlipX();
        }

        //  Problem: The flip and callback and so on gets called for every TweenData that triggers it at the same time.
        //  If you're tweening several properties it can fire for all of them, at once.

        if (tweenData.flipY)
        {
            tweenData.target.toggleFlipY();
        }

        var onYoyo = tween.callbacks.onYoyo;

        if (onYoyo)
        {
            //  Element 1 is reserved for the target of the yoyo (and needs setting here)
            onYoyo.params[1] = tweenData.target;

            onYoyo.func.apply(onYoyo.scope, onYoyo.params);
        }

        tweenData.start = tweenData.getStartValue(tweenData.target, tweenData.key, tweenData.start);

        return TWEEN_CONST.PLAYING_BACKWARD;
    }
    else if (tweenData.repeatCounter > 0)
    {
        //  We've hit the end of a Playing Forward TweenData and we have a Repeat.
        //  So we're going to go right back to the start to repeat it again.

        tweenData.repeatCounter--;

        //  Account for any extra time we got from the previous frame
        tweenData.elapsed = diff;
        tweenData.progress = diff / tweenData.duration;

        // tweenData.elapsed = 0;
        // tweenData.progress = 0;

        if (tweenData.flipX)
        {
            tweenData.target.toggleFlipX();
        }

        if (tweenData.flipY)
        {
            tweenData.target.toggleFlipY();
        }

        var onRepeat = tween.callbacks.onRepeat;

        if (onRepeat)
        {
            //  Element 1 is reserved for the target of the repeat (and needs setting here)
            onRepeat.params[1] = tweenData.target;

            onRepeat.func.apply(onRepeat.scope, onRepeat.params);
        }

        tweenData.start = tweenData.getStartValue(tweenData.target, tweenData.key, tweenData.start);

        tweenData.end = tweenData.getEndValue(tweenData.target, tweenData.key, tweenData.end);

        //  Delay?
        if (tweenData.repeatDelay > 0)
        {
            tweenData.elapsed = tweenData.repeatDelay - diff;

            tweenData.current = tweenData.start;

            tweenData.target[tweenData.key] = tweenData.current;

            return TWEEN_CONST.REPEAT_DELAY;
        }
        else
        {
            return TWEEN_CONST.PLAYING_FORWARD;
        }
    }

    return TWEEN_CONST.COMPLETE;
};

//  Was PLAYING_BACKWARD and has hit the start
var SetStateFromStart = function (tween, tweenData, diff)
{
    if (tweenData.repeatCounter > 0)
    {
        tweenData.repeatCounter--;

        //  Account for any extra time we got from the previous frame
        tweenData.elapsed = diff;
        tweenData.progress = diff / tweenData.duration;

        // tweenData.elapsed = 0;
        // tweenData.progress = 0;

        if (tweenData.flipX)
        {
            tweenData.target.toggleFlipX();
        }

        if (tweenData.flipY)
        {
            tweenData.target.toggleFlipY();
        }

        var onRepeat = tween.callbacks.onRepeat;

        if (onRepeat)
        {
            //  Element 1 is reserved for the target of the repeat (and needs setting here)
            onRepeat.params[1] = tweenData.target;

            onRepeat.func.apply(onRepeat.scope, onRepeat.params);
        }

        tweenData.end = tweenData.getEndValue(tweenData.target, tweenData.key, tweenData.end);

        //  Delay?
        if (tweenData.repeatDelay > 0)
        {
            tweenData.elapsed = tweenData.repeatDelay - diff;

            tweenData.current = tweenData.start;

            tweenData.target[tweenData.key] = tweenData.current;

            return TWEEN_CONST.REPEAT_DELAY;
        }
        else
        {
            return TWEEN_CONST.PLAYING_FORWARD;
        }
    }

    return TWEEN_CONST.COMPLETE;
};

//  Delta is either a value in ms, or 1 if Tween.useFrames is true
var UpdateTweenData = function (tween, tweenData, delta)
{
    switch (tweenData.state)
    {
        case TWEEN_CONST.PLAYING_FORWARD:
        case TWEEN_CONST.PLAYING_BACKWARD:

            var elapsed = tweenData.elapsed;
            var duration = tweenData.duration;
            var diff = 0;

            elapsed += delta;

            if (elapsed > duration)
            {
                diff = elapsed - duration;
                elapsed = duration;
            }

            var forward = (tweenData.state === TWEEN_CONST.PLAYING_FORWARD);
            var progress = elapsed / duration;

            var v;

            if (forward)
            {
                v = tweenData.ease(progress);
            }
            else
            {
                v = tweenData.ease(1 - progress);
            }

            tweenData.current = tweenData.start + ((tweenData.end - tweenData.start) * v);

            tweenData.target[tweenData.key] = tweenData.current;

            tweenData.elapsed = elapsed;
            tweenData.progress = progress;

            var onUpdate = tween.callbacks.onUpdate;

            if (onUpdate)
            {
                onUpdate.params[1] = tweenData.target;

                onUpdate.func.apply(onUpdate.scope, onUpdate.params);
            }

            if (progress === 1)
            {
                if (forward)
                {
                    if (tweenData.hold > 0)
                    {
                        tweenData.elapsed = tweenData.hold - diff;

                        tweenData.state = TWEEN_CONST.HOLD_DELAY;
                    }
                    else
                    {
                        tweenData.state = SetStateFromEnd(tween, tweenData, diff);
                    }
                }
                else
                {
                    tweenData.state = SetStateFromStart(tween, tweenData, diff);
                }
            }

            break;

        case TWEEN_CONST.DELAY:

            tweenData.elapsed -= delta;

            if (tweenData.elapsed <= 0)
            {
                tweenData.elapsed = Math.abs(tweenData.elapsed);

                tweenData.state = TWEEN_CONST.PENDING_RENDER;
            }

            break;

        case TWEEN_CONST.REPEAT_DELAY:

            tweenData.elapsed -= delta;

            if (tweenData.elapsed <= 0)
            {
                tweenData.elapsed = Math.abs(tweenData.elapsed);

                tweenData.state = TWEEN_CONST.PLAYING_FORWARD;
            }

            break;

        case TWEEN_CONST.HOLD_DELAY:

            tweenData.elapsed -= delta;

            if (tweenData.elapsed <= 0)
            {
                tweenData.state = SetStateFromEnd(tween, tweenData);
            }

            break;

        case TWEEN_CONST.PENDING_RENDER:

            tweenData.start = tweenData.getStartValue(tweenData.target, tweenData.key, tweenData.target[tweenData.key]);

            tweenData.end = tweenData.getEndValue(tweenData.target, tweenData.key, tweenData.start);

            tweenData.current = tweenData.start;

            tweenData.target[tweenData.key] = tweenData.start;

            tweenData.state = TWEEN_CONST.PLAYING_FORWARD;

            break;
    }

    //  Return TRUE if this TweenData still playing, otherwise return FALSE
    return (tweenData.state !== TWEEN_CONST.COMPLETE);
};

module.exports = UpdateTweenData;
<commit_msg>Fixed missing diff value<commit_after>var TWEEN_CONST = require('../const');

var SetStateFromEnd = function (tween, tweenData, diff)
{
    if (tweenData.yoyo)
    {
        //  We've hit the end of a Playing Forward TweenData and we have a yoyo

        //  Account for any extra time we got from the previous frame
        tweenData.elapsed = diff;
        tweenData.progress = diff / tweenData.duration;

        if (tweenData.flipX)
        {
            tweenData.target.toggleFlipX();
        }

        //  Problem: The flip and callback and so on gets called for every TweenData that triggers it at the same time.
        //  If you're tweening several properties it can fire for all of them, at once.

        if (tweenData.flipY)
        {
            tweenData.target.toggleFlipY();
        }

        var onYoyo = tween.callbacks.onYoyo;

        if (onYoyo)
        {
            //  Element 1 is reserved for the target of the yoyo (and needs setting here)
            onYoyo.params[1] = tweenData.target;

            onYoyo.func.apply(onYoyo.scope, onYoyo.params);
        }

        tweenData.start = tweenData.getStartValue(tweenData.target, tweenData.key, tweenData.start);

        return TWEEN_CONST.PLAYING_BACKWARD;
    }
    else if (tweenData.repeatCounter > 0)
    {
        //  We've hit the end of a Playing Forward TweenData and we have a Repeat.
        //  So we're going to go right back to the start to repeat it again.

        tweenData.repeatCounter--;

        //  Account for any extra time we got from the previous frame
        tweenData.elapsed = diff;
        tweenData.progress = diff / tweenData.duration;

        // tweenData.elapsed = 0;
        // tweenData.progress = 0;

        if (tweenData.flipX)
        {
            tweenData.target.toggleFlipX();
        }

        if (tweenData.flipY)
        {
            tweenData.target.toggleFlipY();
        }

        var onRepeat = tween.callbacks.onRepeat;

        if (onRepeat)
        {
            //  Element 1 is reserved for the target of the repeat (and needs setting here)
            onRepeat.params[1] = tweenData.target;

            onRepeat.func.apply(onRepeat.scope, onRepeat.params);
        }

        tweenData.start = tweenData.getStartValue(tweenData.target, tweenData.key, tweenData.start);

        tweenData.end = tweenData.getEndValue(tweenData.target, tweenData.key, tweenData.end);

        //  Delay?
        if (tweenData.repeatDelay > 0)
        {
            tweenData.elapsed = tweenData.repeatDelay - diff;

            tweenData.current = tweenData.start;

            tweenData.target[tweenData.key] = tweenData.current;

            return TWEEN_CONST.REPEAT_DELAY;
        }
        else
        {
            return TWEEN_CONST.PLAYING_FORWARD;
        }
    }

    return TWEEN_CONST.COMPLETE;
};

//  Was PLAYING_BACKWARD and has hit the start
var SetStateFromStart = function (tween, tweenData, diff)
{
    if (tweenData.repeatCounter > 0)
    {
        tweenData.repeatCounter--;

        //  Account for any extra time we got from the previous frame
        tweenData.elapsed = diff;
        tweenData.progress = diff / tweenData.duration;

        // tweenData.elapsed = 0;
        // tweenData.progress = 0;

        if (tweenData.flipX)
        {
            tweenData.target.toggleFlipX();
        }

        if (tweenData.flipY)
        {
            tweenData.target.toggleFlipY();
        }

        var onRepeat = tween.callbacks.onRepeat;

        if (onRepeat)
        {
            //  Element 1 is reserved for the target of the repeat (and needs setting here)
            onRepeat.params[1] = tweenData.target;

            onRepeat.func.apply(onRepeat.scope, onRepeat.params);
        }

        tweenData.end = tweenData.getEndValue(tweenData.target, tweenData.key, tweenData.end);

        //  Delay?
        if (tweenData.repeatDelay > 0)
        {
            tweenData.elapsed = tweenData.repeatDelay - diff;

            tweenData.current = tweenData.start;

            tweenData.target[tweenData.key] = tweenData.current;

            return TWEEN_CONST.REPEAT_DELAY;
        }
        else
        {
            return TWEEN_CONST.PLAYING_FORWARD;
        }
    }

    return TWEEN_CONST.COMPLETE;
};

//  Delta is either a value in ms, or 1 if Tween.useFrames is true
var UpdateTweenData = function (tween, tweenData, delta)
{
    switch (tweenData.state)
    {
        case TWEEN_CONST.PLAYING_FORWARD:
        case TWEEN_CONST.PLAYING_BACKWARD:

            var elapsed = tweenData.elapsed;
            var duration = tweenData.duration;
            var diff = 0;

            elapsed += delta;

            if (elapsed > duration)
            {
                diff = elapsed - duration;
                elapsed = duration;
            }

            var forward = (tweenData.state === TWEEN_CONST.PLAYING_FORWARD);
            var progress = elapsed / duration;

            var v;

            if (forward)
            {
                v = tweenData.ease(progress);
            }
            else
            {
                v = tweenData.ease(1 - progress);
            }

            tweenData.current = tweenData.start + ((tweenData.end - tweenData.start) * v);

            tweenData.target[tweenData.key] = tweenData.current;

            tweenData.elapsed = elapsed;
            tweenData.progress = progress;

            var onUpdate = tween.callbacks.onUpdate;

            if (onUpdate)
            {
                onUpdate.params[1] = tweenData.target;

                onUpdate.func.apply(onUpdate.scope, onUpdate.params);
            }

            if (progress === 1)
            {
                if (forward)
                {
                    if (tweenData.hold > 0)
                    {
                        tweenData.elapsed = tweenData.hold - diff;

                        tweenData.state = TWEEN_CONST.HOLD_DELAY;
                    }
                    else
                    {
                        tweenData.state = SetStateFromEnd(tween, tweenData, diff);
                    }
                }
                else
                {
                    tweenData.state = SetStateFromStart(tween, tweenData, diff);
                }
            }

            break;

        case TWEEN_CONST.DELAY:

            tweenData.elapsed -= delta;

            if (tweenData.elapsed <= 0)
            {
                tweenData.elapsed = Math.abs(tweenData.elapsed);

                tweenData.state = TWEEN_CONST.PENDING_RENDER;
            }

            break;

        case TWEEN_CONST.REPEAT_DELAY:

            tweenData.elapsed -= delta;

            if (tweenData.elapsed <= 0)
            {
                tweenData.elapsed = Math.abs(tweenData.elapsed);

                tweenData.state = TWEEN_CONST.PLAYING_FORWARD;
            }

            break;

        case TWEEN_CONST.HOLD_DELAY:

            tweenData.elapsed -= delta;

            if (tweenData.elapsed <= 0)
            {
                tweenData.state = SetStateFromEnd(tween, tweenData, Math.abs(tweenData.elapsed));
            }

            break;

        case TWEEN_CONST.PENDING_RENDER:

            tweenData.start = tweenData.getStartValue(tweenData.target, tweenData.key, tweenData.target[tweenData.key]);

            tweenData.end = tweenData.getEndValue(tweenData.target, tweenData.key, tweenData.start);

            tweenData.current = tweenData.start;

            tweenData.target[tweenData.key] = tweenData.start;

            tweenData.state = TWEEN_CONST.PLAYING_FORWARD;

            break;
    }

    //  Return TRUE if this TweenData still playing, otherwise return FALSE
    return (tweenData.state !== TWEEN_CONST.COMPLETE);
};

module.exports = UpdateTweenData;
<|endoftext|>