<commit_before>var gulp = require('gulp');

var replace = require('gulp-replace');
var ts = require('gulp-typescript');
var concat = require('gulp-concat');
var jeditor = require("gulp-json-editor");
var sourcemaps = require('gulp-sourcemaps');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');

var tsLib = ts.createProject({
    "declarationFiles": false,
    "noExternalResolve": true,
    "module": "commonjs",
});

var tsWeb = ts.createProject({
    "declarationFiles": false,
    "noExternalResolve": true,
    "sortOutput": true,
});

var src = {
    lib: ['lib/*.ts', 'tests/*.ts', '!lib/*-web.ts', '!lib/*.d.ts', 'typings/*/*.d.ts'],
    lib_web: ['lib/util-web.ts', 'lib/util.ts', 'lib/charsets.ts', 'lib/fs-api.ts', 'lib/fs-misc.ts', 'lib/fs-glob.ts', 'lib/fs-sources.ts', 'lib/fs-targets.ts', 'lib/fs-plus.ts', 'lib/channel.ts', 'lib/channel-ws.ts', 'lib/sftp-enums.ts', 'lib/sftp-packet.ts', 'lib/sftp-misc.ts', 'lib/sftp-client.ts', 'lib/sftp-web.ts'],
    pkg: ['package.json'],
    npm: ['.npmignore', '../README.md', '../LICENSE'],
};

var out = {
    lib: '../build',
    lib_web: '../build/web',
};

gulp.task('lib', function () {

    var tsResult = gulp.src(src.lib).pipe(ts(tsLib));

    return tsResult.js
        .pipe(rename(function (path) {
            if (path.basename.substr(path.basename.length - 6) == "-tests")
                path.dirname = "./tests";
            else
                path.dirname = "./lib";
        }))
        .pipe(gulp.dest(out.lib));
});

gulp.task('web.ts', function () {

    return gulp.src(src.lib_web)
        .pipe(replace(/\r/g, ''))
        .pipe(replace(/import (.*) = require\(\"(.*)\"\);.*\n/g, ''))
        .pipe(replace(/import (.*) = (.*);.*\n/g, ''))
        .pipe(replace(/\/\/\/(.*).*\n/g, ''))
        .pipe(replace(/export const/g, 'const'))
        .pipe(replace(/export class/g, 'class'))
        .pipe(replace(/export interface/g, 'interface'))
        .pipe(replace(/export function/g, 'function'))
        .pipe(replace(/new Buffer\(/g, 'new Uint8Array('))
        .pipe(replace(/NodeJS\./g, ''))
        .pipe(replace(/\n.*\/\/ #if NODE(?:(?!#endif\b)[\s\S])*\/\/ #endif.*\n/g, ''))
        .pipe(replace(/^(\s*)(.*)WEB\: /gm, '$1'))
        .pipe(concat('sftp.ts'))
        .pipe(replace(/class Client /g, 'export class Client '))
        .pipe(replace(/^/g, 'module SFTP {'))
        .pipe(replace(/$/g, '\n}'))
        .pipe(replace(/\n/g, '\r\n'))
        .pipe(gulp.dest(out.lib_web));
});

gulp.task('web.js', ['web.ts'], function () {

    var mapOptions = {
        includeContent: false,
        sourceRoot: "./",
    };

    return gulp.src(out.lib_web + '/sftp.ts')
        .pipe(sourcemaps.init())
        .pipe(ts(tsWeb)).js
        .pipe(replace(/^.*\n.*\n.*\n.*\n.*\n.*\nvar SFTP;\n/g, '//\r\n//\r\n//\r\n//\r\n//\r\n\r\nvar SFTP;\r\n'))
        .pipe(replace(/\n};.*\n.*\n.*\n.*\n.*\n.*\nvar SFTP;\n/g, '//\r\n//\r\n//\r\n//\r\n//\r\n\r\nvar SFTP;\r\n'))
        .pipe(sourcemaps.write(".", mapOptions))
        .pipe(gulp.dest(out.lib_web));

});

gulp.task('web', ['web.js'], function () {

    var uglifyOptions = {
        mangle: {
            except: ['SftpItem'],
            screw_ie8: true,
        },
        compress: {
            sequences: true,
            dead_code: true,
            conditionals: true,
            booleans: true,
            unused: true,
            if_return: true,
            join_vars: true,
            drop_console: true,
        },
        output: {
            preamble: "// http://github.com/lukaaash/sftp-ws/",
            //comments: "all",
            //beautify: true,
        }
    };

    return gulp.src(out.lib_web + '/sftp.js')
        .pipe(rename(function (path) { return path.basename = "sftp.min"; }))
        .pipe(uglify(uglifyOptions))
        .pipe(gulp.dest(out.lib_web));
});

gulp.task('package', function () {

    return gulp.src(src.pkg)
        .pipe(jeditor({ 'devDependencies': undefined }))
        .pipe(gulp.dest(out.lib));
});

gulp.task('npm', function () {
    return gulp.src(src.npm)
        .pipe(gulp.dest(out.lib));
});

gulp.task('build', ['lib', 'web', 'package', 'npm'], function () {

});

gulp.task('default', ['build'], function () {

});

<commit_msg>Fixed browser-based closure generator<commit_after>var gulp = require('gulp');

var replace = require('gulp-replace');
var ts = require('gulp-typescript');
var concat = require('gulp-concat');
var jeditor = require("gulp-json-editor");
var sourcemaps = require('gulp-sourcemaps');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');

var tsLib = ts.createProject({
    "declarationFiles": false,
    "noExternalResolve": true,
    "module": "commonjs",
});

var tsWeb = ts.createProject({
    "declarationFiles": false,
    "noExternalResolve": true,
    "sortOutput": true,
});

var src = {
    lib: ['lib/*.ts', 'tests/*.ts', '!lib/*-web.ts', '!lib/*.d.ts', 'typings/*/*.d.ts'],
    lib_web: ['lib/util-web.ts', 'lib/util.ts', 'lib/charsets.ts', 'lib/fs-api.ts', 'lib/fs-misc.ts', 'lib/fs-glob.ts', 'lib/fs-sources.ts', 'lib/fs-targets.ts', 'lib/fs-plus.ts', 'lib/channel.ts', 'lib/channel-ws.ts', 'lib/sftp-enums.ts', 'lib/sftp-packet.ts', 'lib/sftp-misc.ts', 'lib/sftp-client.ts', 'lib/sftp-web.ts'],
    pkg: ['package.json'],
    npm: ['.npmignore', '../README.md', '../LICENSE'],
};

var out = {
    lib: '../build',
    lib_web: '../build/web',
};

gulp.task('lib', function () {

    var tsResult = gulp.src(src.lib).pipe(ts(tsLib));

    return tsResult.js
        .pipe(rename(function (path) {
            if (path.basename.substr(path.basename.length - 6) == "-tests")
                path.dirname = "./tests";
            else
                path.dirname = "./lib";
        }))
        .pipe(gulp.dest(out.lib));
});

gulp.task('web.ts', function () {

    return gulp.src(src.lib_web)
        .pipe(replace(/\r/g, ''))
        .pipe(replace(/import (.*) = require\(\"(.*)\"\);.*\n/g, ''))
        .pipe(replace(/import (.*) = (.*);.*\n/g, ''))
        .pipe(replace(/\/\/\/(.*).*\n/g, ''))
        .pipe(replace(/export const/g, 'const'))
        .pipe(replace(/export class/g, 'class'))
        .pipe(replace(/export interface/g, 'interface'))
        .pipe(replace(/export function/g, 'function'))
        .pipe(replace(/new Buffer\(/g, 'new Uint8Array('))
        .pipe(replace(/NodeJS\./g, ''))
        .pipe(replace(/\n.*\/\/ #if NODE(?:(?!#endif\b)[\s\S])*\/\/ #endif.*\n/g, ''))
        .pipe(replace(/^(\s*)(.*)WEB\: /gm, '$1'))
        .pipe(concat('sftp.ts'))
        .pipe(replace(/class Client /g, 'export class Client '))
        .pipe(replace(/^/g, 'module SFTP {'))
        .pipe(replace(/$/g, '\n}'))
        .pipe(replace(/\n/g, '\r\n'))
        .pipe(gulp.dest(out.lib_web));
});

gulp.task('web.js', ['web.ts'], function () {

    var mapOptions = {
        includeContent: false,
        sourceRoot: "./",
    };

    return gulp.src(out.lib_web + '/sftp.ts')
        .pipe(sourcemaps.init())
        .pipe(ts(tsWeb)).js
        .pipe(replace(/^(.*\n)*var SFTP;\n/g, '//\r\n//\r\n//\r\n//\r\n//\r\n\r\nvar SFTP;\r\n'))
        .pipe(sourcemaps.write(".", mapOptions))
        .pipe(gulp.dest(out.lib_web));

});

gulp.task('web', ['web.js'], function () {

    var uglifyOptions = {
        mangle: {
            except: ['SftpItem'],
            screw_ie8: true,
        },
        compress: {
            sequences: true,
            dead_code: true,
            conditionals: true,
            booleans: true,
            unused: true,
            if_return: true,
            join_vars: true,
            drop_console: true,
        },
        output: {
            preamble: "// http://github.com/lukaaash/sftp-ws/",
            //comments: "all",
            //beautify: true,
        }
    };

    return gulp.src(out.lib_web + '/sftp.js')
        .pipe(rename(function (path) { return path.basename = "sftp.min"; }))
        .pipe(uglify(uglifyOptions))
        .pipe(gulp.dest(out.lib_web));
});

gulp.task('package', function () {

    return gulp.src(src.pkg)
        .pipe(jeditor({ 'devDependencies': undefined }))
        .pipe(gulp.dest(out.lib));
});

gulp.task('npm', function () {
    return gulp.src(src.npm)
        .pipe(gulp.dest(out.lib));
});

gulp.task('build', ['lib', 'web', 'package', 'npm'], function () {

});

gulp.task('default', ['build'], function () {

});

<|endoftext|>


<commit_before>var benchmarkjs = require('benchmark');
var DebugHelper = require('./../../lib/debug-helper');
var should = require('should');

var FakeLogger = function(){

  this.logStack = [];

  var self = this;

  this.log = function(message){
    self.logStack.push(message);
  };

};

describe('log function', function(){

  it('should correctly log simple messages', function(done) {

    var fakeLogger = new FakeLogger(),
        debugHelper = new DebugHelper(fakeLogger);

    debugHelper.simpleLog("Message");

    fakeLogger.logStack[0].should.be.eql("Message");
    done();
  });

  it('should correctly log messages', function(done) {

    var fakeLogger = new FakeLogger(),
        debugHelper = new DebugHelper(fakeLogger);

    debugHelper.log("Message");

    fakeLogger.logStack[0].should.be.eql("======================================");
    fakeLogger.logStack[1].should.be.eql("Message");
    fakeLogger.logStack[2].should.be.eql("");

    done();
  });

  it('should correctly log comparison result in case of comparison', function(done) {

    var fakeLogger = new FakeLogger(),
        debugHelper = new DebugHelper(fakeLogger);

    debugHelper.log("Message");

    fakeLogger.logStack[0].should.be.eql("======================================");
    fakeLogger.logStack[1].should.be.eql("Message");
    fakeLogger.logStack[2].should.be.eql("");

    done();
  });

  it('should correctly log nothing if it is not enabled', function(done) {

    var fakeLogger = new FakeLogger(),
        debugHelper = new DebugHelper(fakeLogger);

    debugHelper.shutUp();

    debugHelper.simpleLog("Message");
    debugHelper.log("Message");

    fakeLogger.logStack.length.should.be.eql(0);
    done();
  });
});<commit_msg>dependecy fix<commit_after>var DebugHelper = require('./../../lib/debug-helper');
var should = require('should');

var FakeLogger = function(){

  this.logStack = [];

  var self = this;

  this.log = function(message){
    self.logStack.push(message);
  };

};

describe('log function', function(){

  it('should correctly log simple messages', function(done) {

    var fakeLogger = new FakeLogger(),
        debugHelper = new DebugHelper(fakeLogger);

    debugHelper.simpleLog("Message");

    fakeLogger.logStack[0].should.be.eql("Message");
    done();
  });

  it('should correctly log messages', function(done) {

    var fakeLogger = new FakeLogger(),
        debugHelper = new DebugHelper(fakeLogger);

    debugHelper.log("Message");

    fakeLogger.logStack[0].should.be.eql("======================================");
    fakeLogger.logStack[1].should.be.eql("Message");
    fakeLogger.logStack[2].should.be.eql("");

    done();
  });

  it('should correctly log comparison result in case of comparison', function(done) {

    var fakeLogger = new FakeLogger(),
        debugHelper = new DebugHelper(fakeLogger);

    debugHelper.log("Message");

    fakeLogger.logStack[0].should.be.eql("======================================");
    fakeLogger.logStack[1].should.be.eql("Message");
    fakeLogger.logStack[2].should.be.eql("");

    done();
  });

  it('should correctly log nothing if it is not enabled', function(done) {

    var fakeLogger = new FakeLogger(),
        debugHelper = new DebugHelper(fakeLogger);

    debugHelper.shutUp();

    debugHelper.simpleLog("Message");
    debugHelper.log("Message");

    fakeLogger.logStack.length.should.be.eql(0);
    done();
  });
});<|endoftext|>


<commit_before>'use strict';

/* globals describe, it, beforeEach, afterEach, sinon, Imager */

describe('Imager.js HTML data-* API', function(){
  // Simili-Array.map for IE8 compat purpose
  var applyEach = Imager.applyEach;

  describe('handling {width} in data-src', function(){
    var fixtures;

    afterEach(function(){
      cleanFixtures(fixtures);
    });

    it('should not use RegExp anymore', function(done){
      fixtures = loadFixtures('data-src-old');
      var imgr = new Imager({ availableWidths: [320, 640] });

      runAfterAnimationFrame(function(){
        applyEach(imgr.divs, function(el){
          expect(el).to.have.property('nodeName', 'IMG');
          expect(el.src).to.contain(el.getAttribute('data-src'));
        });

        done();
      });
    });

    it('should replace {width} by the computed width or a fallback', function(done){
      fixtures = loadFixtures('data-src-new');
      var imgr = new Imager({ availableWidths: [640, 320] });

      runAfterAnimationFrame(function(){
        var src = applyEach(imgr.divs, function(el){ return el.getAttribute('src'); });

        expect(src).to.eql([
          'base/test/fixtures/media/C-320.jpg',
          'base/test/fixtures/media/B-640.jpg',
          'base/test/fixtures/media-320/fillmurray.jpg'
        ]);

        done();
      });
    });

    it('should interpolate {width} with an alternate string value', function(done){
      fixtures = loadFixtures('data-src-interpolate');
      var imgr = new Imager({ availableWidths: {1024: '', 320: 'n_d', 640: 'z_d'} });

      runAfterAnimationFrame(function(){
        var src = applyEach(imgr.divs, function(el){ return el.getAttribute('src'); });

        expect(src).to.eql([
          'base/test/fixtures/interpolated/B-n_d.jpg',
          'base/test/fixtures/interpolated/B-z_d.jpg',
          'base/test/fixtures/1024/1024.jpg'
        ]);

        done();
      });
    });

    it('should interpolate {width} based on an interpolation function', function(done){
      fixtures = loadFixtures('data-src-interpolate');
      var imgr = new Imager({
        availableWidths: [320, 640, 1024],
        widthInterpolator: function(w) {
          if (w == 320) { return 'n_d'; }
          if (w == 640) { return 'z_d'; }
          return '';
        }
      });

      runAfterAnimationFrame(function(){
        var src = imgr.divs.map(function(el){ return el.getAttribute('src'); });

        expect(src).to.eql([
          'base/test/fixtures/interpolated/B-n_d.jpg',
          'base/test/fixtures/interpolated/B-z_d.jpg',
          'base/test/fixtures/1024/1024.jpg'
        ]);

        done();
      });
    });
  });

  describe('Imager.getPixelRatio', function(){
      var sandbox;

      beforeEach(function(){
          sandbox = sinon.sandbox.create();
      });

      afterEach(function(){
          sandbox.restore();
      });

      it('should return a numeric value', function(){
        expect(Imager.getPixelRatio()).to.be.above(0);
      });

      it('should return a default value of 1 for old browser', function (){
        expect(Imager.getPixelRatio({})).to.equal(1);
      });
  });

  describe('handling {pixel_ratio} in data-src', function(){
    var sandbox;

    beforeEach(function(){
      sandbox = sinon.sandbox.create();
    });

    afterEach(function(){
      sandbox.restore();
    });

    it('should transform {pixel_ratio} as "" or "-<pixel ratio value>x"', function(){
      expect(Imager.transforms.pixelRatio(1)).to.equal('');
      expect(Imager.transforms.pixelRatio(0.5)).to.equal('-0.5x');
      expect(Imager.transforms.pixelRatio(1.5)).to.equal('-1.5x');
    });

    it('should replace {pixel_ratio} from the `data-src`', function(){
      var dataSrc,
          imgr = new Imager();

      dataSrc = 'http://example.com/img{pixel_ratio}/A-{width}.jpg';
      sandbox.stub(imgr, 'devicePixelRatio', 1);
      expect(imgr.changeImageSrcToUseNewImageDimensions(dataSrc, 320)).to.equal('http://example.com/img/A-320.jpg');
      sandbox.stub(imgr, 'devicePixelRatio', 2);
      expect(imgr.changeImageSrcToUseNewImageDimensions(dataSrc, 320)).to.equal('http://example.com/img-2x/A-320.jpg');

      dataSrc = 'http://example.com/img{pixel_ratio}/A.jpg';
      sandbox.stub(imgr, 'devicePixelRatio', 1);
      expect(imgr.changeImageSrcToUseNewImageDimensions(dataSrc, 320)).to.equal('http://example.com/img/A.jpg');
      sandbox.stub(imgr, 'devicePixelRatio', 2);
      expect(imgr.changeImageSrcToUseNewImageDimensions(dataSrc, 320)).to.equal('http://example.com/img-2x/A.jpg');
    });
  });

  describe('handling data-alt', function(){
    var fixtures;

    afterEach(function(){
      cleanFixtures(fixtures);
    });

    it('should generate an empty alt attribute for the responsive image', function(done){
        fixtures = loadFixtures('regular');
        var imgr = new Imager('#main .delayed-image-load');

        expect(imgr.gif).to.have.property('alt', '');

        runAfterAnimationFrame(function(){
            expect(imgr.divs[0]).to.have.property('alt', imgr.gif.alt);

            done();
        });
    });

    it('should generate an alt attribute with the same value as the placeholder data-alt attribute', function(done){
      fixtures = loadFixtures('regular');
      var imgr = new Imager('#main .delayed-image-load');

      expect(imgr.gif).to.have.property('alt', '');

      runAfterAnimationFrame(function(){
        expect(imgr.divs[1]).to.have.property('alt', 'Responsive Image alternative');

        done();
      });
    });
  });
});
<commit_msg>Fixing an `Array.prototype.map` in tests breaking w/ IE8.<commit_after>'use strict';

/* globals describe, it, beforeEach, afterEach, sinon, Imager */

describe('Imager.js HTML data-* API', function(){
  // Simili-Array.map for IE8 compat purpose
  var applyEach = Imager.applyEach;

  describe('handling {width} in data-src', function(){
    var fixtures;

    afterEach(function(){
      cleanFixtures(fixtures);
    });

    it('should not use RegExp anymore', function(done){
      fixtures = loadFixtures('data-src-old');
      var imgr = new Imager({ availableWidths: [320, 640] });

      runAfterAnimationFrame(function(){
        applyEach(imgr.divs, function(el){
          expect(el).to.have.property('nodeName', 'IMG');
          expect(el.src).to.contain(el.getAttribute('data-src'));
        });

        done();
      });
    });

    it('should replace {width} by the computed width or a fallback', function(done){
      fixtures = loadFixtures('data-src-new');
      var imgr = new Imager({ availableWidths: [640, 320] });

      runAfterAnimationFrame(function(){
        var src = applyEach(imgr.divs, function(el){ return el.getAttribute('src'); });

        expect(src).to.eql([
          'base/test/fixtures/media/C-320.jpg',
          'base/test/fixtures/media/B-640.jpg',
          'base/test/fixtures/media-320/fillmurray.jpg'
        ]);

        done();
      });
    });

    it('should interpolate {width} with an alternate string value', function(done){
      fixtures = loadFixtures('data-src-interpolate');
      var imgr = new Imager({ availableWidths: {1024: '', 320: 'n_d', 640: 'z_d'} });

      runAfterAnimationFrame(function(){
        var src = applyEach(imgr.divs, function(el){ return el.getAttribute('src'); });

        expect(src).to.eql([
          'base/test/fixtures/interpolated/B-n_d.jpg',
          'base/test/fixtures/interpolated/B-z_d.jpg',
          'base/test/fixtures/1024/1024.jpg'
        ]);

        done();
      });
    });

    it('should interpolate {width} based on an interpolation function', function(done){
      fixtures = loadFixtures('data-src-interpolate');
      var imgr = new Imager({
        availableWidths: [320, 640, 1024],
        widthInterpolator: function(w) {
          if (w == 320) { return 'n_d'; }
          if (w == 640) { return 'z_d'; }
          return '';
        }
      });

      runAfterAnimationFrame(function(){
        var src = applyEach(imgr.divs, function(el){ return el.getAttribute('src'); });

        expect(src).to.eql([
          'base/test/fixtures/interpolated/B-n_d.jpg',
          'base/test/fixtures/interpolated/B-z_d.jpg',
          'base/test/fixtures/1024/1024.jpg'
        ]);

        done();
      });
    });
  });

  describe('Imager.getPixelRatio', function(){
      var sandbox;

      beforeEach(function(){
          sandbox = sinon.sandbox.create();
      });

      afterEach(function(){
          sandbox.restore();
      });

      it('should return a numeric value', function(){
        expect(Imager.getPixelRatio()).to.be.above(0);
      });

      it('should return a default value of 1 for old browser', function (){
        expect(Imager.getPixelRatio({})).to.equal(1);
      });
  });

  describe('handling {pixel_ratio} in data-src', function(){
    var sandbox;

    beforeEach(function(){
      sandbox = sinon.sandbox.create();
    });

    afterEach(function(){
      sandbox.restore();
    });

    it('should transform {pixel_ratio} as "" or "-<pixel ratio value>x"', function(){
      expect(Imager.transforms.pixelRatio(1)).to.equal('');
      expect(Imager.transforms.pixelRatio(0.5)).to.equal('-0.5x');
      expect(Imager.transforms.pixelRatio(1.5)).to.equal('-1.5x');
    });

    it('should replace {pixel_ratio} from the `data-src`', function(){
      var dataSrc,
          imgr = new Imager();

      dataSrc = 'http://example.com/img{pixel_ratio}/A-{width}.jpg';
      sandbox.stub(imgr, 'devicePixelRatio', 1);
      expect(imgr.changeImageSrcToUseNewImageDimensions(dataSrc, 320)).to.equal('http://example.com/img/A-320.jpg');
      sandbox.stub(imgr, 'devicePixelRatio', 2);
      expect(imgr.changeImageSrcToUseNewImageDimensions(dataSrc, 320)).to.equal('http://example.com/img-2x/A-320.jpg');

      dataSrc = 'http://example.com/img{pixel_ratio}/A.jpg';
      sandbox.stub(imgr, 'devicePixelRatio', 1);
      expect(imgr.changeImageSrcToUseNewImageDimensions(dataSrc, 320)).to.equal('http://example.com/img/A.jpg');
      sandbox.stub(imgr, 'devicePixelRatio', 2);
      expect(imgr.changeImageSrcToUseNewImageDimensions(dataSrc, 320)).to.equal('http://example.com/img-2x/A.jpg');
    });
  });

  describe('handling data-alt', function(){
    var fixtures;

    afterEach(function(){
      cleanFixtures(fixtures);
    });

    it('should generate an empty alt attribute for the responsive image', function(done){
        fixtures = loadFixtures('regular');
        var imgr = new Imager('#main .delayed-image-load');

        expect(imgr.gif).to.have.property('alt', '');

        runAfterAnimationFrame(function(){
            expect(imgr.divs[0]).to.have.property('alt', imgr.gif.alt);

            done();
        });
    });

    it('should generate an alt attribute with the same value as the placeholder data-alt attribute', function(done){
      fixtures = loadFixtures('regular');
      var imgr = new Imager('#main .delayed-image-load');

      expect(imgr.gif).to.have.property('alt', '');

      runAfterAnimationFrame(function(){
        expect(imgr.divs[1]).to.have.property('alt', 'Responsive Image alternative');

        done();
      });
    });
  });
});
<|endoftext|>


<commit_before>$(document).ready(function(){
    var nofinv = 1;
    $('#id_invoicenumber').addClass('invoice'+' '+nofinv);
    $('#id_invoicestatus').addClass('invoiceadditional'+' '+nofinv);
    $('#id_paidon').addClass('paid'+' '+nofinv);
    $('#id_rejectreason').addClass('reject'+' '+nofinv);
    $("#id_amount").addClass("amount"+" "+nofinv);
    $("#id_currency").addClass("currency"+" "+nofinv);
    $("#id_reasonother").addClass("other"+" "+nofinv);
    $('.addhiddendata:first').find('#id_invoicenumber').attr('id', 'id_invoicenumber'+nofinv);
    $('.addhiddendata:first').find('#id_invoicestatus').attr('id', 'id_invoicestatus'+nofinv);
    $('.addhiddendata:first').find('#id_paidon').attr('id', 'id_paidon'+nofinv);
    $('.addhiddendata:first').find('#id_rejectreason').attr('id', 'id_rejectreason'+nofinv);
    $(".addhiddendata:first").find("#id_amount").attr("id", "id_amount"+nofinv);
    $(".addhiddendata:first").find("#id_currency").attr("id", "id_currency"+nofinv);
    $("#id_reasonother").attr("id", "id_reasonother"+nofinv);

    $('#trbutton').on('click', function(){
	$('#trbutton').fadeOut('slow', function(){
	    $('#trform').fadeIn('slow');
	    $('#ptrack').html('Please fill in all the fields.');
	});
    });

    $('#id_reminderdate').datepicker({
	dateFormat: 'yy-mm-dd',
	constrainInput: false
    });

    $('.paid:first').datepicker({
	dateFormat: 'yy-mm-dd',
	constrainInput: false
    });

    var $name = $('#vclerk').attr('value');
    $('#id_clerk').val($name);

    $('#id_clerk').attr('readonly', true);
    $('#id_actiondate').attr('readonly', true);

    $('#id_market').on('change', function(){
	//show the ccode choice if is hidden
	if ($('#id_ccode').is(':hidden')) {$('#id_ccode').show()};

	$('#id_ccode option').each(function(){
	    $(this).show();
	});

	var market = $('#id_market').val();
	if (market == 'IT') {
	    var marketArray = ['', '11', '13', '15', '16'];
	} else if (market == 'DE') {
	    var marketArray = ['', '13', '52', '55', '60', '64', '66'];
	} else if (market == 'PT' || market == 'PL' || market == 'NL' || market == 'NO') {
	    var marketArray = ['', '10'];
	} else if (market == 'BE') {
	    var marketArray = ['', '12', '14', '18', '31'];
	} else if (market == 'SE') {
	    var marketArray = ['', '16'];
	} else if (market == 'FI') {
	    var marketArray = ['', '11'];
	} else if (market == 'DK') {
	    var marketArray = ['', '12'];
	} else {
	    var marketArray = [''];
	}

	$('#id_ccode option').each(function(){
	    var ccodeOpt = $(this).val();
	    if ($.inArray(ccodeOpt, marketArray) > -1){
		;
	    } else {
		$(this).hide();
	    }
	});

    });

    $(document).on('change', '.status', function() {
	var status = $(this).val();
	var nextform = $(this).parent().parent().parent().next();

	if (nextform.is(':hidden')){
	    ;
	} else {
	    nextform.hide();
	    if (nextform.find('.paid').is(':hidden')) {nextform.find('.paid').show()};
	    if (nextform.find('.other').is(':hidden')) {nextform.find('.other').show()};
	    if (nextform.find('.reject').is(':hidden')) {nextform.find('.reject').show()};
	    nextform.find('label').show();
	}

	if (status == 'RJ'){
	    nextform.find('.paid').hide();
	    nextform.find('label:last').hide();
	    nextform.fadeIn('slow');
	} else if (status == 'PD') {
	    nextform.find('.reject').hide();
	    nextform.find(".other").hide();
	    nextform.find('label:first').hide();
	    nextform.find('label:first').next().next("label").hide();
	    nextform.fadeIn('slow');
	};
    });

    $('#addbutt').on('click', function() {
	var formToApp = $('.addhiddendata:first').clone();
	formToApp.find('button').remove();
	formToApp.find('.paid').removeClass('hasDatepicker');
	formToApp.find('.paid').val('');
	formToApp.find('#id_invoicenumber1').removeClass('invoice'+' '+nofinv);
	formToApp.find('#id_invoicestatus1').removeClass('invoiceadditional'+' '+nofinv);
	formToApp.find('#id_paidon1').removeClass('paid'+' '+nofinv);
	formToApp.find('#id_rejectreason1').removeClass('reject'+' '+nofinv);
	formToApp.find("#id_amount1").removeClass("amount"+" "+nofinv);
	formToApp.find("#id_currency1").removeClass("currency"+" "+nofinv);
	formToApp.find("#id_reasonother1").removeClass("other"+" "+nofinv);
	nofinv = nofinv + 1;
	formToApp.find('#id_rejectreason1').addClass('reject'+' '+nofinv);
	formToApp.find('#id_rejectreason1').attr('name', 'reject'+nofinv);
	formToApp.find('#id_rejectreason1').attr('id', 'id_rejectreason'+nofinv);
	formToApp.find('#id_paidon1').addClass('paid'+' '+nofinv);
	formToApp.find('#id_paidon1').attr('name', 'paid'+nofinv);
	formToApp.find('#id_paidon1').attr('id', 'id_paidon'+nofinv);
	formToApp.find('#id_invoicenumber1').addClass('invoice'+' '+nofinv);
	formToApp.find('#id_invoicenumber1').attr('name', 'invoicenumber'+nofinv);
	formToApp.find('#id_invoicenumber1').attr('id', 'id_invoicenumber'+nofinv);
	formToApp.find('#id_invoicestatus1').addClass('invoiceadditional'+' '+nofinv);
	formToApp.find('#id_invoicestatus1').attr('name', 'invoicestatus'+nofinv);
	formToApp.find('#id_invoicestatus1').attr('id', 'id_invoicestatus'+nofinv);
	formToApp.find("#id_amount1").addClass("amount"+" "+nofinv);
	formToApp.find("#id_amount1").attr("name", "amount"+nofinv);
	formToApp.find("#id_amount1").attr("id", "id_amount"+nofinv);
	formToApp.find("#id_currency1").addClass("currency"+" "+nofinv);
	formToApp.find("#id_currency1").attr("name", "currency"+nofinv);
	formToApp.find("#id_currency1").attr("id", "id_currency"+nofinv);
	formToApp.find('#id_reasonother1').addClass('other'+' '+nofinv);
	formToApp.find('#id_reasonother1').attr('name', 'reasonother'+nofinv);
	formToApp.find('#id_reasonother1').attr('id', 'id_reasonother'+nofinv);
	$('#vendorform').before(formToApp);
	formToApp.find('.paid').datepicker({
	    dateFormat: 'yy-mm-dd',
	    constrainInput: false
	});
    });

    $('#rembutt').on('click', function() {
	//Remove additional invoices if there are at least 2 of them.
	if ($('.invoice').length == 1) {
	    ;
	} else {
	    $('.addhiddendata:last').remove();
	};
    });

    $('#id_reminderdate').on('change', function() {
	var rdate = $(this).val().split('-');
	var market = $('#id_market').val();
	$('#id_remindernumber').val('');
	$('#id_remindernumber').val(market+rdate[0]+rdate[1]+rdate[2]+'/');
    });

    function DunningTrack() {
	// get the total number of invoices.
	var invo = $('.invoice').length;

	var data = new Array()

	//loop through the invoice to create our data to post
	for (x = 1; x <= invo; x++) {
	    var formn = 'form'+x;
	    var obj = {
		market: $('#id_market').val(),
		ccode: $('#id_ccode').val(),
		clerk: $('#id_clerk').val(),
		actiondate: $('#id_actiondate').val(),
		reminderdate: $('#id_actiondate').val(),
		level: $('#id_level').val(),
		amount: $("#id_amount"+x).val(),
		currency: $("#id_currency"+x).val(),
		remindernumber: $('#id_remindernumber').val(),
		vendor: $('#id_vendor').val(),
		mailvendor: $('#id_mailvendor').val(),
		invoicenumber: $('#id_invoicenumber'+x).val(),
		invoicestatus: $('#id_invoicestatus'+x).val(),
		actiontaken: actionArray(),
		rejectreason: $('#id_rejectreason'+x).val(),
		paidon: $('#id_paidon'+x).val()
		//attachment:
	    };
	    data.push(obj);
	}

	//setup the AJAX request
	$.ajaxSetup({
	    type: 'POST',
	    dataType: 'json'
	});

	//the real AJAX request
	$.ajax({
	    url: '/ajax/',
	    data: {
		form_type: 'multi',
		mass_data: JSON.stringify(data)
	    },
	    success: function() {
		SuccessfulTracking();
	    },
	    error: function (ajaxObj, textStatus, error) {
		alert(error);
	    }
	});
	return true;
    };

    $('#trackbutton').on('click', function() {
	if ( ValidateForm() == 0 ) { AjaxUpload() };
    });

    $("#trform :input").on("change", function() {
	if ( $(this).val() != "" ) {
	    if ( $(this).parent().parent().hasClass("has-error") ) {
		$(this).parent().parent().removeClass("has-error");
	    }
	}
    });

});

function SuccessfulTracking() {
    alert("Item correctly tracked");
};

function actionArray() {
    var actionPool = $(".actioncheck :input");
    var actionList = new Array()

    $.each(actionPool, function() {
	if ( $(this).prop("checked") ) { actionList.push($(this).val()) }
    });

    actionList = actionList.join(",")
    return actionList;
};

function ValidateForm() {
    error = 0;
    var howManyErrors = $(".has-error").length;
    var fieldsToCheck = ["market", "ccode", "reminderdate", "remindernumber",
			 "level", "vendor", "mailvendor"]
    if ( howManyErrors == 0 ) {
	//checks if some fields are not correctly filled (1st check)
	$.each(fieldsToCheck, function() {
	    if ($("#id_"+this).val() == "") {
		if (! $("#id_"+this).parent().parent().hasClass("has-error")) {
		    $("#id_"+this).parent().parent().addClass("has-error");
		    error++;
		}
	    } else {
		if ($("id_"+this).parent().parent().hasClass(".has-error")) {
		    $("#id_"+this).removeClass("has-error");
		}
	    };
	});
    } else {
	// no errors
	;
    }
    // return the total number of errors
    var errorSum = error + additionalErrorCheck()
    return errorSum
};

function additionalErrorCheck() {
    var error = 0;
    var vendor = $("#id_vendor")
    var mailVendor = $("#id_mailvendor")

    //check if email field is e-mail like
    if ( !isValidEmailAddress(mailVendor.val()) ) {
	if ( !mailVendor.hasClass("has-error") ) { mailVendor.parent().parent().addClass("has-error") }
	error++
    };

    //check if vendor number has 9 characters or if starts with 100 or if there are no characters into the field
    if ( !(vendor.val().length == 9) || !(vendor.val().substr(0, 3) == "100") || !isInteger(vendor.val()) ) {
	if ( ! vendor.hasClass("has-error") ) { vendor.parent().parent().addClass("has-error") }
	error++
    };

    //returns the number of errors
    return error
};

function isValidEmailAddress(emailAddress) {
    var pattern = new RegExp(/^(("[\w-+\s]+")|([\w-+]+(?:\.[\w-+]+)*)|("[\w-+\s]+")([\w-+]+(?:\.[\w-+]+)*))(@((?:[\w-+]+\.)*\w[\w-+]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$)|(@\[?((25[0-5]\.|2[0-4][\d]\.|1[\d]{2}\.|[\d]{1,2}\.))((25[0-5]|2[0-4][\d]|1[\d]{2}|[\d]{1,2})\.){2}(25[0-5]|2[0-4][\d]|1[\d]{2}|[\d]{1,2})\]?$)/i);
    return pattern.test(emailAddress);
};

function isInteger(value) {
    var intPattern = new RegExp(/^[0-9]+$/)
    return intPattern.test(value);
};
<commit_msg>The function now accepts an argument. The argument is supposed to be a must but we have to be sure that if it is not will be properly escaped by jQuery. <-- TO DO<commit_after>$(document).ready(function(){
    var nofinv = 1;
    $('#id_invoicenumber').addClass('invoice'+' '+nofinv);
    $('#id_invoicestatus').addClass('invoiceadditional'+' '+nofinv);
    $('#id_paidon').addClass('paid'+' '+nofinv);
    $('#id_rejectreason').addClass('reject'+' '+nofinv);
    $("#id_amount").addClass("amount"+" "+nofinv);
    $("#id_currency").addClass("currency"+" "+nofinv);
    $("#id_reasonother").addClass("other"+" "+nofinv);
    $('.addhiddendata:first').find('#id_invoicenumber').attr('id', 'id_invoicenumber'+nofinv);
    $('.addhiddendata:first').find('#id_invoicestatus').attr('id', 'id_invoicestatus'+nofinv);
    $('.addhiddendata:first').find('#id_paidon').attr('id', 'id_paidon'+nofinv);
    $('.addhiddendata:first').find('#id_rejectreason').attr('id', 'id_rejectreason'+nofinv);
    $(".addhiddendata:first").find("#id_amount").attr("id", "id_amount"+nofinv);
    $(".addhiddendata:first").find("#id_currency").attr("id", "id_currency"+nofinv);
    $("#id_reasonother").attr("id", "id_reasonother"+nofinv);

    $('#trbutton').on('click', function(){
	$('#trbutton').fadeOut('slow', function(){
	    $('#trform').fadeIn('slow');
	    $('#ptrack').html('Please fill in all the fields.');
	});
    });

    $('#id_reminderdate').datepicker({
	dateFormat: 'yy-mm-dd',
	constrainInput: false
    });

    $('.paid:first').datepicker({
	dateFormat: 'yy-mm-dd',
	constrainInput: false
    });

    var $name = $('#vclerk').attr('value');
    $('#id_clerk').val($name);

    $('#id_clerk').attr('readonly', true);
    $('#id_actiondate').attr('readonly', true);

    $('#id_market').on('change', function(){
	//show the ccode choice if is hidden
	if ($('#id_ccode').is(':hidden')) {$('#id_ccode').show()};

	$('#id_ccode option').each(function(){
	    $(this).show();
	});

	var market = $('#id_market').val();
	if (market == 'IT') {
	    var marketArray = ['', '11', '13', '15', '16'];
	} else if (market == 'DE') {
	    var marketArray = ['', '13', '52', '55', '60', '64', '66'];
	} else if (market == 'PT' || market == 'PL' || market == 'NL' || market == 'NO') {
	    var marketArray = ['', '10'];
	} else if (market == 'BE') {
	    var marketArray = ['', '12', '14', '18', '31'];
	} else if (market == 'SE') {
	    var marketArray = ['', '16'];
	} else if (market == 'FI') {
	    var marketArray = ['', '11'];
	} else if (market == 'DK') {
	    var marketArray = ['', '12'];
	} else {
	    var marketArray = [''];
	}

	$('#id_ccode option').each(function(){
	    var ccodeOpt = $(this).val();
	    if ($.inArray(ccodeOpt, marketArray) > -1){
		;
	    } else {
		$(this).hide();
	    }
	});

    });

    $(document).on('change', '.status', function() {
	var status = $(this).val();
	var nextform = $(this).parent().parent().parent().next();

	if (nextform.is(':hidden')){
	    ;
	} else {
	    nextform.hide();
	    if (nextform.find('.paid').is(':hidden')) {nextform.find('.paid').show()};
	    if (nextform.find('.other').is(':hidden')) {nextform.find('.other').show()};
	    if (nextform.find('.reject').is(':hidden')) {nextform.find('.reject').show()};
	    nextform.find('label').show();
	}

	if (status == 'RJ'){
	    nextform.find('.paid').hide();
	    nextform.find('label:last').hide();
	    nextform.fadeIn('slow');
	} else if (status == 'PD') {
	    nextform.find('.reject').hide();
	    nextform.find(".other").hide();
	    nextform.find('label:first').hide();
	    nextform.find('label:first').next().next("label").hide();
	    nextform.fadeIn('slow');
	};
    });

    $('#addbutt').on('click', function() {
	var formToApp = $('.addhiddendata:first').clone();
	formToApp.find('button').remove();
	formToApp.find('.paid').removeClass('hasDatepicker');
	formToApp.find('.paid').val('');
	formToApp.find('#id_invoicenumber1').removeClass('invoice'+' '+nofinv);
	formToApp.find('#id_invoicestatus1').removeClass('invoiceadditional'+' '+nofinv);
	formToApp.find('#id_paidon1').removeClass('paid'+' '+nofinv);
	formToApp.find('#id_rejectreason1').removeClass('reject'+' '+nofinv);
	formToApp.find("#id_amount1").removeClass("amount"+" "+nofinv);
	formToApp.find("#id_currency1").removeClass("currency"+" "+nofinv);
	formToApp.find("#id_reasonother1").removeClass("other"+" "+nofinv);
	nofinv = nofinv + 1;
	formToApp.find('#id_rejectreason1').addClass('reject'+' '+nofinv);
	formToApp.find('#id_rejectreason1').attr('name', 'reject'+nofinv);
	formToApp.find('#id_rejectreason1').attr('id', 'id_rejectreason'+nofinv);
	formToApp.find('#id_paidon1').addClass('paid'+' '+nofinv);
	formToApp.find('#id_paidon1').attr('name', 'paid'+nofinv);
	formToApp.find('#id_paidon1').attr('id', 'id_paidon'+nofinv);
	formToApp.find('#id_invoicenumber1').addClass('invoice'+' '+nofinv);
	formToApp.find('#id_invoicenumber1').attr('name', 'invoicenumber'+nofinv);
	formToApp.find('#id_invoicenumber1').attr('id', 'id_invoicenumber'+nofinv);
	formToApp.find('#id_invoicestatus1').addClass('invoiceadditional'+' '+nofinv);
	formToApp.find('#id_invoicestatus1').attr('name', 'invoicestatus'+nofinv);
	formToApp.find('#id_invoicestatus1').attr('id', 'id_invoicestatus'+nofinv);
	formToApp.find("#id_amount1").addClass("amount"+" "+nofinv);
	formToApp.find("#id_amount1").attr("name", "amount"+nofinv);
	formToApp.find("#id_amount1").attr("id", "id_amount"+nofinv);
	formToApp.find("#id_currency1").addClass("currency"+" "+nofinv);
	formToApp.find("#id_currency1").attr("name", "currency"+nofinv);
	formToApp.find("#id_currency1").attr("id", "id_currency"+nofinv);
	formToApp.find('#id_reasonother1').addClass('other'+' '+nofinv);
	formToApp.find('#id_reasonother1').attr('name', 'reasonother'+nofinv);
	formToApp.find('#id_reasonother1').attr('id', 'id_reasonother'+nofinv);
	$('#vendorform').before(formToApp);
	formToApp.find('.paid').datepicker({
	    dateFormat: 'yy-mm-dd',
	    constrainInput: false
	});
    });

    $('#rembutt').on('click', function() {
	//Remove additional invoices if there are at least 2 of them.
	if ($('.invoice').length == 1) {
	    ;
	} else {
	    $('.addhiddendata:last').remove();
	};
    });

    $('#id_reminderdate').on('change', function() {
	var rdate = $(this).val().split('-');
	var market = $('#id_market').val();
	$('#id_remindernumber').val('');
	$('#id_remindernumber').val(market+rdate[0]+rdate[1]+rdate[2]+'/');
    });

    function DunningTrack(id) {
	// get the total number of invoices.
	var invo = $('.invoice').length;

	var data = new Array()

	//loop through the invoice to create our data to post
	for (x = 1; x <= invo; x++) {
	    var formn = 'form'+x;
	    var obj = {
		market: $('#id_market').val(),
		ccode: $('#id_ccode').val(),
		clerk: $('#id_clerk').val(),
		actiondate: $('#id_actiondate').val(),
		reminderdate: $('#id_actiondate').val(),
		level: $('#id_level').val(),
		amount: $("#id_amount"+x).val(),
		currency: $("#id_currency"+x).val(),
		remindernumber: $('#id_remindernumber').val(),
		vendor: $('#id_vendor').val(),
		mailvendor: $('#id_mailvendor').val(),
		invoicenumber: $('#id_invoicenumber'+x).val(),
		invoicestatus: $('#id_invoicestatus'+x).val(),
		actiontaken: actionArray(),
		rejectreason: $('#id_rejectreason'+x).val(),
		paidon: $('#id_paidon'+x).val()
		//attachment:
	    };
	    data.push(obj);
	}

	//setup the AJAX request
	$.ajaxSetup({
	    type: 'POST',
	    dataType: 'json'
	});

	//the real AJAX request
	$.ajax({
	    url: '/ajax/',
	    data: {
		form_type: 'multi',
		mass_data: JSON.stringify(data)
	    },
	    success: function() {
		SuccessfulTracking();
	    },
	    error: function (ajaxObj, textStatus, error) {
		alert(error);
	    }
	});
	return true;
    };

    $('#trackbutton').on('click', function() {
	if ( ValidateForm() == 0 ) { AjaxUpload() };
    });

    $("#trform :input").on("change", function() {
	if ( $(this).val() != "" ) {
	    if ( $(this).parent().parent().hasClass("has-error") ) {
		$(this).parent().parent().removeClass("has-error");
	    }
	}
    });

});

function SuccessfulTracking() {
    alert("Item correctly tracked");
};

function actionArray() {
    var actionPool = $(".actioncheck :input");
    var actionList = new Array()

    $.each(actionPool, function() {
	if ( $(this).prop("checked") ) { actionList.push($(this).val()) }
    });

    actionList = actionList.join(",")
    return actionList;
};

function ValidateForm() {
    error = 0;
    var howManyErrors = $(".has-error").length;
    var fieldsToCheck = ["market", "ccode", "reminderdate", "remindernumber",
			 "level", "vendor", "mailvendor"]
    if ( howManyErrors == 0 ) {
	//checks if some fields are not correctly filled (1st check)
	$.each(fieldsToCheck, function() {
	    if ($("#id_"+this).val() == "") {
		if (! $("#id_"+this).parent().parent().hasClass("has-error")) {
		    $("#id_"+this).parent().parent().addClass("has-error");
		    error++;
		}
	    } else {
		if ($("id_"+this).parent().parent().hasClass(".has-error")) {
		    $("#id_"+this).removeClass("has-error");
		}
	    };
	});
    } else {
	// no errors
	;
    }
    // return the total number of errors
    var errorSum = error + additionalErrorCheck()
    return errorSum
};

function additionalErrorCheck() {
    var error = 0;
    var vendor = $("#id_vendor")
    var mailVendor = $("#id_mailvendor")

    //check if email field is e-mail like
    if ( !isValidEmailAddress(mailVendor.val()) ) {
	if ( !mailVendor.hasClass("has-error") ) { mailVendor.parent().parent().addClass("has-error") }
	error++
    };

    //check if vendor number has 9 characters or if starts with 100 or if there are no characters into the field
    if ( !(vendor.val().length == 9) || !(vendor.val().substr(0, 3) == "100") || !isInteger(vendor.val()) ) {
	if ( ! vendor.hasClass("has-error") ) { vendor.parent().parent().addClass("has-error") }
	error++
    };

    //returns the number of errors
    return error
};

function isValidEmailAddress(emailAddress) {
    var pattern = new RegExp(/^(("[\w-+\s]+")|([\w-+]+(?:\.[\w-+]+)*)|("[\w-+\s]+")([\w-+]+(?:\.[\w-+]+)*))(@((?:[\w-+]+\.)*\w[\w-+]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$)|(@\[?((25[0-5]\.|2[0-4][\d]\.|1[\d]{2}\.|[\d]{1,2}\.))((25[0-5]|2[0-4][\d]|1[\d]{2}|[\d]{1,2})\.){2}(25[0-5]|2[0-4][\d]|1[\d]{2}|[\d]{1,2})\]?$)/i);
    return pattern.test(emailAddress);
};

function isInteger(value) {
    var intPattern = new RegExp(/^[0-9]+$/)
    return intPattern.test(value);
};
<|endoftext|>


<commit_before>import React from 'react';
import _ from 'lodash'
import PropTypes from 'prop-types'
import { ListView, ActivityIndicator, WingBlank } from 'antd-mobile'
import styles from './ProListView.css';
import Card from '../Card.js'

function MyBody({ children }) {
  return (
    <WingBlank>

        {children}

    </WingBlank>
  )
}

let index = 0
class ProListView extends React.Component {
  constructor(props) {
    super(props)
    const getSectionData = (dataBlob, sectionID) => dataBlob[sectionID]
    const getRowData = (dataBlob, sectionID, rowID) => dataBlob[rowID]
    const dataSource = new ListView.DataSource({
      getRowData,
      getSectionHeaderData: getSectionData,
      rowHasChanged: (row1, row2) => row1 !== row2,
      sectionHeaderHasChanged: (s1, s2) => s1 !== s2
    })
    const { data = {}, PER_PAGE = 10 } = this.props
    this.dataBlob = data.dataBlob || {}
    this.sectionIDs = data.sectionIDs || []
    this.rowIDs = data.rowIDs || []
    this.genData = (pIndex = 0) => {
      console.log('gen-data');
      const sectionName = `Section ${pIndex}`
      if (this.sectionIDs.includes(sectionName)) return
      this.sectionIDs.push(sectionName)
      this.dataBlob[sectionName] = sectionName
      this.rowIDs[pIndex] = []
      for (let i = 0; i < PER_PAGE; i++) {
        const rowName = `S${pIndex}, R${i}`
        this.rowIDs[pIndex].push(rowName)
        this.dataBlob[rowName] = rowName
      }
      this.rowIDs = [].concat(this.rowIDs)
      this.sectionIDs = [].concat(this.sectionIDs)
    }

    this.state = {
      dataSource: dataSource
        .cloneWithRowsAndSections(this.dataBlob, this.sectionIDs, this.rowIDs),
      isLoading: false
    }
  }

  componentWillMount() {
    index = 0
  }

  componentWillReceiveProps(nextProps) {
    const { page } = nextProps
    console.log(page);
    console.log(nextProps.fetching);
    if (page === null) return
    if (nextProps.fetching) {
      index = 0
      return
    }
    // console.log('will receive props, and page is ', page, ' index is ', index);
    this.genData(nextProps.page);
    this.setState({
      dataSource: this.state.dataSource
        .cloneWithRowsAndSections(this.dataBlob, this.sectionIDs, this.rowIDs),
      isLoading: false
    })
  }

  shouldComponentUpdate() {
    const { replace, BodyComponent, store, fetching } = this.props
    if (!replace || !BodyComponent || _.isEmpty(store) || fetching) return true
    return true
  }

  componentWillUnmount() {
    const { onUpdate } = this.props
    if (onUpdate) onUpdate(this.dataBlob, this.sectionIDs, this.rowIDs)
  }

  onEndReached = () => {
    console.log('reached');
    if (this.state.isLoading || !this.props.hasMore) {
      return
    }
    this.setState({ isLoading: true })
    const { onLoadMore } = this.props
    setTimeout(() => {
      onLoadMore()
    }, 1000)
  }

  onScroll = (e) => {
    console.log(e.target.scrollTop);
  }

  lv = null

  render() {
    console.log('render');
    const { lists, PER_PAGE = 10, RowComponent = Card,
      BodyComponent = MyBody, store, fetching } = this.props
    const row = (rowDta, sectionId, rowID) => {
      const pro = lists[index]
      index += 1
      if (!pro) return null
      return (
        <RowComponent key={rowID} customStyle={{ marginTop: '.25rem' }} data={store[pro]} />
      )
    }
    return (

        {
          fetching
            ? null
            : (
              <ListView
                ref={(el) => { this.lv = el }}
                dataSource={this.state.dataSource}
                renderFooter={() => (

                    {
                      this.state.isLoading
                        ? <ActivityIndicator text="加载中..." size="small" />
                        : null
                    }

                )}
                renderBodyComponent={() => <BodyComponent />}
                className={styles.list_box}
                renderRow={row}
                initialListSize={PER_PAGE - 2}
                pageSize={PER_PAGE >> 1}
                scrollRenderAheadDistance={500}
                scrollEventThrottle={200}
                onEndReached={this.onEndReached}
                onEndReachedThreshold={10}
                scrollerOptions={{ scrollbars: true }}
              />
            )
        }

    )
  }
}

ProListView.PropTypes = {
  store: PropTypes.object.isRequired,
  lists: PropTypes.array.isRequired,
  page: PropTypes.number.isRequired,
  hasMore: PropTypes.bool.isRequired,
  data: PropTypes.object,
  RowComponent: PropTypes.element,
  BodyComponent: PropTypes.element,
  replace: PropTypes.bool,
  fetching: PropTypes.bool,
  onLoadMore: PropTypes.func.isRequired,
  onUpdate: PropTypes.func
}

export default ProListView;
<commit_msg>add no more -mac<commit_after>import React from 'react';
import _ from 'lodash'
import PropTypes from 'prop-types'
import { ListView, ActivityIndicator, WingBlank } from 'antd-mobile'
import styles from './ProListView.css';
import Card from '../Card.js'

function MyBody({ children }) {
  return (
    <WingBlank>

        {children}

    </WingBlank>
  )
}

let index = 0
class ProListView extends React.Component {
  constructor(props) {
    super(props)
    const getSectionData = (dataBlob, sectionID) => dataBlob[sectionID]
    const getRowData = (dataBlob, sectionID, rowID) => dataBlob[rowID]
    const dataSource = new ListView.DataSource({
      getRowData,
      getSectionHeaderData: getSectionData,
      rowHasChanged: (row1, row2) => row1 !== row2,
      sectionHeaderHasChanged: (s1, s2) => s1 !== s2
    })
    const { data = {}, PER_PAGE = 10 } = this.props
    this.dataBlob = data.dataBlob || {}
    this.sectionIDs = data.sectionIDs || []
    this.rowIDs = data.rowIDs || []
    this.genData = (pIndex = 0) => {
      console.log('gen-data');
      const sectionName = `Section ${pIndex}`
      if (this.sectionIDs.includes(sectionName)) return
      this.sectionIDs.push(sectionName)
      this.dataBlob[sectionName] = sectionName
      this.rowIDs[pIndex] = []
      for (let i = 0; i < PER_PAGE; i++) {
        const rowName = `S${pIndex}, R${i}`
        this.rowIDs[pIndex].push(rowName)
        this.dataBlob[rowName] = rowName
      }
      this.rowIDs = [].concat(this.rowIDs)
      this.sectionIDs = [].concat(this.sectionIDs)
    }

    this.state = {
      dataSource: dataSource
        .cloneWithRowsAndSections(this.dataBlob, this.sectionIDs, this.rowIDs),
      isLoading: false
    }
  }

  componentWillMount() {
    index = 0
  }

  componentWillReceiveProps(nextProps) {
    const { page } = nextProps
    console.log(page);
    console.log(nextProps.fetching);
    if (page === null) return
    if (nextProps.fetching) {
      index = 0
      return
    }
    // console.log('will receive props, and page is ', page, ' index is ', index);
    this.genData(nextProps.page);
    this.setState({
      dataSource: this.state.dataSource
        .cloneWithRowsAndSections(this.dataBlob, this.sectionIDs, this.rowIDs),
      isLoading: false
    })
  }

  shouldComponentUpdate() {
    const { replace, BodyComponent, store, fetching } = this.props
    if (!replace || !BodyComponent || _.isEmpty(store) || fetching) return true
    return true
  }

  componentWillUnmount() {
    const { onUpdate } = this.props
    if (onUpdate) onUpdate(this.dataBlob, this.sectionIDs, this.rowIDs)
  }

  onEndReached = () => {
    console.log('reached');
    if (this.state.isLoading || !this.props.hasMore) {
      return
    }
    this.setState({ isLoading: true })
    const { onLoadMore } = this.props
    setTimeout(() => {
      onLoadMore()
    }, 1000)
  }

  onScroll = (e) => {
    console.log(e.target.scrollTop);
  }

  lv = null

  render() {
    console.log('render');
    const { lists, PER_PAGE = 10, RowComponent = Card,
      BodyComponent = MyBody, store, fetching, hasMore } = this.props
    const row = (rowDta, sectionId, rowID) => {
      const pro = lists[index]
      index += 1
      if (!pro) return null
      return (
        <RowComponent key={rowID} customStyle={{ marginTop: '.25rem' }} data={store[pro]} />
      )
    }
    return (

        {
          fetching
            ? null
            : (
              <ListView
                ref={(el) => { this.lv = el }}
                dataSource={this.state.dataSource}
                renderFooter={() => (

                    {
                      this.state.isLoading
                        ? <ActivityIndicator text="加载中..." size="small" />
                        : (
                          hasMore ? null : '没有更多了'
                        )
                    }

                )}
                renderBodyComponent={() => <BodyComponent />}
                className={styles.list_box}
                renderRow={row}
                initialListSize={PER_PAGE - 2}
                pageSize={PER_PAGE >> 1}
                scrollRenderAheadDistance={500}
                scrollEventThrottle={200}
                onEndReached={this.onEndReached}
                onEndReachedThreshold={10}
                scrollerOptions={{ scrollbars: true }}
              />
            )
        }

    )
  }
}

ProListView.PropTypes = {
  store: PropTypes.object.isRequired,
  lists: PropTypes.array.isRequired,
  page: PropTypes.number.isRequired,
  hasMore: PropTypes.bool.isRequired,
  data: PropTypes.object,
  RowComponent: PropTypes.element,
  BodyComponent: PropTypes.element,
  replace: PropTypes.bool,
  fetching: PropTypes.bool,
  onLoadMore: PropTypes.func.isRequired,
  onUpdate: PropTypes.func
}

export default ProListView;
<|endoftext|>


<commit_before>require(__dirname+'/test-helper');

var buffers = {};
buffers.readyForQuery = function() {
  return new BufferList()
    .add(Buffer('I'))
    .join(true,'Z');
};

buffers.authenticationOk = function() {
  return new BufferList()
    .addInt32(0)
    .join(true, 'R');
};

buffers.parameterStatus = function(name, value) {
  return new BufferList()
    .addCString(name)
    .addCString(value)
    .join(true, 'S');
};

buffers.backendKeyData = function(processID, secretKey) {
  return new BufferList()
    .addInt32(processID)
    .addInt32(secretKey)
    .join(true, 'K');
};

buffers.commandComplete = function(string) {
  return new BufferList()
    .addCString(string)
    .join(true, 'C');
};

buffers.rowDescription = function(fields) {
  fields = fields || [];
  var buf = new BufferList();
  buf.addInt16(fields.length);
  fields.forEach(function(field) {
    buf.addCString(field.name)
      .addInt32(field.tableID || 0)
      .addInt16(field.attributeNumber || 0)
      .addInt32(field.dataTypeID || 0)
      .addInt16(field.dataTypeSize || 0)
      .addInt32(field.typeModifier || 0)
      .addInt16(field.formatCode || 0)
  });
  return buf.join(true, 'T');
};

buffers.dataRow = function(columns) {
  columns = columns || [];
  var buf = new BufferList();
  buf.addInt16(columns.length);
  columns.forEach(function(col) {
    if(col == null) {
      buf.addInt32(-1);
    } else {
      var strBuf = new Buffer(col, 'utf8');
      buf.addInt32(strBuf.length);
      buf.add(strBuf);
    }
  });
  return buf.join(true, 'D');
};

buffers.error = function(fields) {
  fields = fields || [];
  var buf = new BufferList();
  fields.forEach(function(field) {
    buf.addChar(field.type);
    buf.addCString(field.value);
  });
  buf.add(Buffer([0]));//terminator
  return buf.join(true, 'E');
};

module.exports = buffers;
<commit_msg>link to documentation<commit_after>require(__dirname+'/test-helper');
//http://developer.postgresql.org/pgdocs/postgres/protocol-message-formats.html

var buffers = {};
buffers.readyForQuery = function() {
  return new BufferList()
    .add(Buffer('I'))
    .join(true,'Z');
};

buffers.authenticationOk = function() {
  return new BufferList()
    .addInt32(0)
    .join(true, 'R');
};

buffers.parameterStatus = function(name, value) {
  return new BufferList()
    .addCString(name)
    .addCString(value)
    .join(true, 'S');
};

buffers.backendKeyData = function(processID, secretKey) {
  return new BufferList()
    .addInt32(processID)
    .addInt32(secretKey)
    .join(true, 'K');
};

buffers.commandComplete = function(string) {
  return new BufferList()
    .addCString(string)
    .join(true, 'C');
};

buffers.rowDescription = function(fields) {
  fields = fields || [];
  var buf = new BufferList();
  buf.addInt16(fields.length);
  fields.forEach(function(field) {
    buf.addCString(field.name)
      .addInt32(field.tableID || 0)
      .addInt16(field.attributeNumber || 0)
      .addInt32(field.dataTypeID || 0)
      .addInt16(field.dataTypeSize || 0)
      .addInt32(field.typeModifier || 0)
      .addInt16(field.formatCode || 0)
  });
  return buf.join(true, 'T');
};

buffers.dataRow = function(columns) {
  columns = columns || [];
  var buf = new BufferList();
  buf.addInt16(columns.length);
  columns.forEach(function(col) {
    if(col == null) {
      buf.addInt32(-1);
    } else {
      var strBuf = new Buffer(col, 'utf8');
      buf.addInt32(strBuf.length);
      buf.add(strBuf);
    }
  });
  return buf.join(true, 'D');
};

buffers.error = function(fields) {
  fields = fields || [];
  var buf = new BufferList();
  fields.forEach(function(field) {
    buf.addChar(field.type);
    buf.addCString(field.value);
  });
  buf.add(Buffer([0]));//terminator
  return buf.join(true, 'E');
};

module.exports = buffers;
<|endoftext|>


<commit_before>const _ = require('lodash'),
  filterableList = require('../filterable-list'),
  addComponent = require('../components/add-component'),
  pane = require('./');

/**
 * open the add component pane
 * @param {array} components
 * @param {object} options to call addComponent with
 * @returns {Element}
 */
function openAddComponent(components, options) {
  var header = 'Add Component',
    innerEl = filterableList.create(components, {
      click: function (id) {
        return addComponent(options.pane, options.field, id, options.ref)
          .then(() => close()); // only close pane if we added successfully
      }
    });

  return pane.open([{header: header, content: innerEl}]);
}

module.exports = openAddComponent;
_.set(window, 'kiln.services.panes.openAddComponent', module.exports);
<commit_msg>Calling pane.close instead of close() which might close a tab (#607)<commit_after>const _ = require('lodash'),
  filterableList = require('../filterable-list'),
  addComponent = require('../components/add-component'),
  pane = require('./');

/**
 * open the add component pane
 * @param {array} components
 * @param {object} options to call addComponent with
 * @returns {Element}
 */
function openAddComponent(components, options) {
  var header = 'Add Component',
    innerEl = filterableList.create(components, {
      click: function (id) {
        return addComponent(options.pane, options.field, id, options.ref)
          .then(() => pane.close()); // only close pane if we added successfully
      }
    });

  return pane.open([{header: header, content: innerEl}]);
}

module.exports = openAddComponent;
_.set(window, 'kiln.services.panes.openAddComponent', module.exports);
<|endoftext|>


<commit_before>'use strict';

// Imports
const {testingUtils} = require('@gkalpak/cli-utils');
const {readFileSync} = require('fs');
const {join} = require('path');
const {VIMRC_PATH} = require('../../lib/constants');
const {ROOT_DIR} = require('../test-utils');

// Constants
const SCRIPT_DIR = 'bin/config/';

// Tests
describe(SCRIPT_DIR, () => {
  describe('cfgbash', () => {
    const testScript = testingUtils.testScriptFactory(join(ROOT_DIR, SCRIPT_DIR, 'cfgbash'));

    it('should print configuration instructions for `bash`', async () => {
      const result = await testScript();

      expect(result).toMatch(/^### Copy the following into '~\/\.bashrc':/);
      expect(result).toMatch(/bind "TAB:menu-complete";$/);
    });
  });

  describe('cfggit', () => {
    const testScript = testingUtils.testScriptFactory(join(ROOT_DIR, SCRIPT_DIR, 'cfggit'));

    it('should print configuration instructions for `git`', async () => {
      const result = await testScript();

      expect(result).toMatch(/^### Run the following commands:/);
      expect(result).toMatch(/git config --global mergetool\.kdiff3\.trustExitCode false$/);
    });
  });

  describe('cfgvim', () => {
    const testScript = testingUtils.testScriptFactory(join(ROOT_DIR, SCRIPT_DIR, 'cfgvim'));

    it('should print configuration instructions for `vim`', async () => {
      const vimrcContent = readFileSync(VIMRC_PATH, 'utf8').trim();
      const result = await testScript();

      expect(result).toMatch(/^""" Copy the following into '~\/\.vimrc':/);
      expect(result).toContain(vimrcContent);
    });
  });
});
<commit_msg>test(config): fix `cfgvim` test on Windows<commit_after>'use strict';

// Imports
const {testingUtils} = require('@gkalpak/cli-utils');
const {readFileSync} = require('fs');
const {join} = require('path');
const {VIMRC_PATH} = require('../../lib/constants');
const {ROOT_DIR} = require('../test-utils');

// Constants
const SCRIPT_DIR = 'bin/config/';

// Tests
describe(SCRIPT_DIR, () => {
  describe('cfgbash', () => {
    const testScript = testingUtils.testScriptFactory(join(ROOT_DIR, SCRIPT_DIR, 'cfgbash'));

    it('should print configuration instructions for `bash`', async () => {
      const result = await testScript();

      expect(result).toMatch(/^### Copy the following into '~\/\.bashrc':/);
      expect(result).toMatch(/bind "TAB:menu-complete";$/);
    });
  });

  describe('cfggit', () => {
    const testScript = testingUtils.testScriptFactory(join(ROOT_DIR, SCRIPT_DIR, 'cfggit'));

    it('should print configuration instructions for `git`', async () => {
      const result = await testScript();

      expect(result).toMatch(/^### Run the following commands:/);
      expect(result).toMatch(/git config --global mergetool\.kdiff3\.trustExitCode false$/);
    });
  });

  describe('cfgvim', () => {
    const testScript = testingUtils.testScriptFactory(join(ROOT_DIR, SCRIPT_DIR, 'cfgvim'));

    it('should print configuration instructions for `vim`', async () => {
      const vimrcContent = readFileSync(VIMRC_PATH, 'utf8').trim().replace(/\r\n/g, '\n');
      const result = await testScript();

      expect(result).toMatch(/^""" Copy the following into '~\/\.vimrc':/);
      expect(result).toContain(vimrcContent);
    });
  });
});
<|endoftext|>


<commit_before>const { fork } = require('child_process');
const fs = require('fs');
const path = require('path');

const assert = require('chai').assert;
const chokidar = require('chokidar');
const cpr = require('cpr');
const request = require('superagent');
const rimraf = require('rimraf');
const tmp = require('tmp');
const yaml = require('js-yaml');

const { findOpenPortNumbers } = require('../common/server-helper');

/*
    1) Copy config to a temp directory.
    2) Execute a child process with `process.env.EG_CONFIG_DIR` set to the temp directory.
    3) Watch the temp directory config file from the test.
    4) Do a baseline request to make sure the original gateway config is working.
    5) Write a new gateway config
    6) When the test watcher fires, make another HTTP request to confirm the new config is working.
    7) Clean up the temp directory.
*/

const baseConfigDirectory = path.join(__dirname, '..', 'fixtures', 'hot-reload');

describe('hot-reload', () => {
  describe('gateway config', () => {
    let testGatewayConfigPath = null;
    let testGatewayConfigData = null;
    let childProcess = null;
    let originalGatewayPort = null;

    before(function (done) {
      this.timeout(10000);
      tmp.dir((err, tempPath) => {
        if (err) {
          return done(err);
        }

        cpr(baseConfigDirectory, tempPath, (err, files) => {
          if (err) {
            return done(err);
          }

          testGatewayConfigPath = path.join(tempPath, 'gateway.config.yml');

          findOpenPortNumbers(3).then(ports => {
            if (err) {
              return done(err);
            }

            fs.readFile(testGatewayConfigPath, (err, configData) => {
              if (err) {
                return done(err);
              }

              testGatewayConfigData = yaml.load(configData);

              testGatewayConfigData.http.port = ports[0];
              testGatewayConfigData.https.port = ports[1];
              testGatewayConfigData.admin.port = ports[2];
              testGatewayConfigData.serviceEndpoints.backend.url =
                `http://localhost:${ports[2]}`;

              originalGatewayPort = ports[0];

              fs.writeFile(testGatewayConfigPath, yaml.dump(testGatewayConfigData), (err) => {
                if (err) {
                  return done(err);
                }

                const childEnv = Object.assign({}, process.env);
                childEnv.EG_CONFIG_DIR = tempPath;

                // Tests, by default have config watch disabled.
                // Need to remove this paramter in the child process.
                delete childEnv.EG_DISABLE_CONFIG_WATCH;

                const modulePath = path.join(__dirname, '../..', 'lib', 'index.js');
                childProcess = fork(modulePath, [], {
                  cwd: tempPath,
                  env: childEnv
                });

                childProcess.on('error', err => {
                  return done(err);
                });

                // Not ideal, but we need to make sure the process is running.
                setTimeout(() => {
                  request
                    .get(`http://localhost:${originalGatewayPort}`)
                    .end((err, res) => {
                      assert(err);
                      assert(res.unauthorized);
                      done();
                    });
                }, 5000);
              });
            });
          }).catch(done);
        });
      });
    });

    after(done => {
      childProcess.kill();
      rimraf(testGatewayConfigPath, done);
    });

    it('reloads valid gateway.config.yml', done => {
      const watchOptions = {
        awaitWriteFinish: true
      };

      const watcher = chokidar.watch(testGatewayConfigPath, watchOptions);
      watcher.once('change', (evt) => {
        request
          .get(`http://localhost:${originalGatewayPort}`)
          .end((err, res) => {
            assert(err);
            assert(res.clientError);
            assert.equal(res.statusCode, 404);
            done();
          });
      });

      watcher.on('ready', () => {
        // remove key-auth policy
        testGatewayConfigData.pipelines.adminAPI.policies.shift();

        fs.writeFile(testGatewayConfigPath, yaml.dump(testGatewayConfigData), (err) => {
          if (err) {
            return done(err);
          }
        });
      });
    }).timeout(10000);

    it('uses previous config on reload of invalid gateway.config.yml', done => {
      const watchOptions = {
        awaitWriteFinish: true
      };

      const watcher = chokidar.watch(testGatewayConfigPath, watchOptions);
      watcher.once('change', (evt) => {
        request
          .get(`http://localhost:${originalGatewayPort}`)
          .end((err, res) => {
            assert(err);
            assert(res.clientError);
            assert.equal(res.statusCode, 404);
            done();
          });
      });

      watcher.on('ready', () => {
        // make config invalid
        delete testGatewayConfigData.pipelines;

        fs.writeFile(testGatewayConfigPath, yaml.dump(testGatewayConfigData), (err) => {
          if (err) {
            return done(err);
          }
        });
      });
    }).timeout(10000);
  });
});
<commit_msg>Remove wrong err checking<commit_after>const { fork } = require('child_process');
const fs = require('fs');
const path = require('path');

const assert = require('chai').assert;
const chokidar = require('chokidar');
const cpr = require('cpr');
const request = require('superagent');
const rimraf = require('rimraf');
const tmp = require('tmp');
const yaml = require('js-yaml');

const { findOpenPortNumbers } = require('../common/server-helper');

/*
    1) Copy config to a temp directory.
    2) Execute a child process with `process.env.EG_CONFIG_DIR` set to the temp directory.
    3) Watch the temp directory config file from the test.
    4) Do a baseline request to make sure the original gateway config is working.
    5) Write a new gateway config
    6) When the test watcher fires, make another HTTP request to confirm the new config is working.
    7) Clean up the temp directory.
*/

const baseConfigDirectory = path.join(__dirname, '..', 'fixtures', 'hot-reload');

describe('hot-reload', () => {
  describe('gateway config', () => {
    let testGatewayConfigPath = null;
    let testGatewayConfigData = null;
    let childProcess = null;
    let originalGatewayPort = null;

    before(function (done) {
      this.timeout(10000);
      tmp.dir((err, tempPath) => {
        if (err) {
          return done(err);
        }

        cpr(baseConfigDirectory, tempPath, (err, files) => {
          if (err) {
            return done(err);
          }

          testGatewayConfigPath = path.join(tempPath, 'gateway.config.yml');

          findOpenPortNumbers(3).then(ports => {
            fs.readFile(testGatewayConfigPath, (err, configData) => {
              if (err) {
                return done(err);
              }

              testGatewayConfigData = yaml.load(configData);

              testGatewayConfigData.http.port = ports[0];
              testGatewayConfigData.https.port = ports[1];
              testGatewayConfigData.admin.port = ports[2];
              testGatewayConfigData.serviceEndpoints.backend.url =
                `http://localhost:${ports[2]}`;

              originalGatewayPort = ports[0];

              fs.writeFile(testGatewayConfigPath, yaml.dump(testGatewayConfigData), (err) => {
                if (err) {
                  return done(err);
                }

                const childEnv = Object.assign({}, process.env);
                childEnv.EG_CONFIG_DIR = tempPath;

                // Tests, by default have config watch disabled.
                // Need to remove this paramter in the child process.
                delete childEnv.EG_DISABLE_CONFIG_WATCH;

                const modulePath = path.join(__dirname, '../..', 'lib', 'index.js');
                childProcess = fork(modulePath, [], {
                  cwd: tempPath,
                  env: childEnv
                });

                childProcess.on('error', err => {
                  return done(err);
                });

                // Not ideal, but we need to make sure the process is running.
                setTimeout(() => {
                  request
                    .get(`http://localhost:${originalGatewayPort}`)
                    .end((err, res) => {
                      assert(res.unauthorized);
                      done(err);
                    });
                }, 5000);
              });
            });
          }).catch(done);
        });
      });
    });

    after(done => {
      childProcess.kill();
      rimraf(testGatewayConfigPath, done);
    });

    it('reloads valid gateway.config.yml', done => {
      const watchOptions = {
        awaitWriteFinish: true
      };

      const watcher = chokidar.watch(testGatewayConfigPath, watchOptions);
      watcher.once('change', (evt) => {
        request
          .get(`http://localhost:${originalGatewayPort}`)
          .end((err, res) => {
            assert(err);
            assert(res.clientError);
            assert.equal(res.statusCode, 404);
            done();
          });
      });

      watcher.on('ready', () => {
        // remove key-auth policy
        testGatewayConfigData.pipelines.adminAPI.policies.shift();

        fs.writeFile(testGatewayConfigPath, yaml.dump(testGatewayConfigData), (err) => {
          if (err) {
            return done(err);
          }
        });
      });
    }).timeout(10000);

    it('uses previous config on reload of invalid gateway.config.yml', done => {
      const watchOptions = {
        awaitWriteFinish: true
      };

      const watcher = chokidar.watch(testGatewayConfigPath, watchOptions);
      watcher.once('change', (evt) => {
        request
          .get(`http://localhost:${originalGatewayPort}`)
          .end((err, res) => {
            assert(err);
            assert(res.clientError);
            assert.equal(res.statusCode, 404);
            done();
          });
      });

      watcher.on('ready', () => {
        // make config invalid
        delete testGatewayConfigData.pipelines;

        fs.writeFile(testGatewayConfigPath, yaml.dump(testGatewayConfigData), (err) => {
          if (err) {
            return done(err);
          }
        });
      });
    }).timeout(10000);
  });
});
<|endoftext|>


<commit_before>import React from 'react';
import { findDOMNode } from 'react-dom';
import moment from 'moment';
import {
	Button,
	Col,
	Form,
	FormField,
	FormInput,
	ResponsiveText,
	Row,
	Spinner,
} from 'elemental';

import AlertMessages from '../../../shared/AlertMessages';
import ConfirmationDialog from './../../../shared/ConfirmationDialog';
import Fields from '../../../../utils/fields';

import FormHeading from './FormHeading';
import AltText from './AltText';
import FooterBar from './FooterBar';
import InvalidFieldType from '../../../shared/InvalidFieldType';

import { deleteItem } from '../actions';

function upCase (str) {
	return str.slice(0, 1).toUpperCase() + str.substr(1).toLowerCase();
};

function getNameFromData (data) {
	if (typeof data === 'object') {
		if (typeof data.first === 'string' && typeof data.last === 'string') {
			return data.first + ' ' + data.last;
		} else if (data.id) {
			return data.id;
		}
	}
	return data;
}

var EditForm = React.createClass({
	displayName: 'EditForm',
	propTypes: {
		data: React.PropTypes.object,
		list: React.PropTypes.object,
	},
	getInitialState () {
		return {
			values: Object.assign({}, this.props.data.fields),
			confirmationDialog: null,
			loading: false,
		};
	},
	getFieldProps (field) {
		const props = Object.assign({}, field);
		const alerts = this.state.alerts;
		// Display validation errors inline
		if (alerts && alerts.error && alerts.error.error === 'validation errors') {
			if (alerts.error.detail[field.path]) {
				// NOTE: This won't work yet, as ElementalUI doesn't allow
				// passed in isValid, only invalidates via internal state.
				// PR to fix that: https://github.com/elementalui/elemental/pull/149
				props.isValid = false;
			}
		}
		props.value = this.state.values[field.path];
		props.values = this.state.values;
		props.onChange = this.handleChange;
		props.mode = 'edit';
		return props;
	},
	handleChange (event) {
		const values = Object.assign({}, this.state.values);

		values[event.path] = event.value;
		this.setState({ values });
	},
	confirmReset (event) {
		const confirmationDialog = (
			<ConfirmationDialog
				isOpen
				body={`Reset your changes to <strong>${this.props.data.name}</strong>?`}
				confirmationLabel="Reset"
				onCancel={this.removeConfirmationDialog}
				onConfirmation={this.handleReset}
			/>
		);
		event.preventDefault();
		this.setState({ confirmationDialog });
	},
	handleReset () {
		this.setState({
			values: Object.assign({}, this.props.data.fields),
			confirmationDialog: null,
		});
	},
	confirmDelete () {
		const confirmationDialog = (
			<ConfirmationDialog
				isOpen
				body={`Are you sure you want to delete <strong>${this.props.data.name}?</strong><br /><br />This cannot be undone.`}
				confirmationLabel="Delete"
				onCancel={this.removeConfirmationDialog}
				onConfirmation={this.handleDelete}
			/>
		);
		this.setState({ confirmationDialog });
	},
	handleDelete () {
		const { data, list } = this.props;
		this.props.dispatch(deleteItem(data.id, this.props.router));
	},
	handleKeyFocus () {
		const input = findDOMNode(this.refs.keyOrIdInput);
		input.select();
	},
	removeConfirmationDialog () {
		this.setState({
			confirmationDialog: null,
		});
	},
	updateItem () {
		const { data, list } = this.props;
		const editForm = this.refs.editForm.getDOMNode();
		const formData = new FormData(editForm);

		// Clear alerts
		this.setState({
			alerts: null,
			loading: true,
		});

		list.updateItem(data.id, formData, (err, data) => {
			// TODO: implement smooth scolling
			scrollTo(0, 0); // Scroll to top
			if (err) {
				this.setState({
					alerts: {
						error: err,
					},
					loading: false,
				});
			} else {
				// Success, display success flash messages, replace values
				// TODO: Update key value
				this.setState({
					alerts: {
						success: {
							success: 'update success',
						},
					},
					values: data.fields,
					loading: false,
				});
			}
		});
	},
	renderKeyOrId () {
		var className = 'EditForm__key-or-id';
		var list = this.props.list;

		if (list.nameField && list.autokey && this.props.data[list.autokey.path]) {
			return (

					<AltText
						normal={`${upCase(list.autokey.path)}: `}
						modified="ID:"
						component="span"
						title="Press <alt> to reveal the ID"
						className="EditForm__key-or-id__label" />
					<AltText
						normal={<input ref="keyOrIdInput" onFocus={this.handleKeyFocus} value={this.props.data[list.autokey.path]} className="EditForm__key-or-id__input" readOnly />}
						modified={<input ref="keyOrIdInput" onFocus={this.handleKeyFocus} value={this.props.data.id} className="EditForm__key-or-id__input" readOnly />}
						component="span"
						title="Press <alt> to reveal the ID"
						className="EditForm__key-or-id__field" />

			);
		} else if (list.autokey && this.props.data[list.autokey.path]) {
			return (

					{list.autokey.path}:

						<input ref="keyOrIdInput" onFocus={this.handleKeyFocus} value={this.props.data[list.autokey.path]} className="EditForm__key-or-id__input" readOnly />

			);
		} else if (list.nameField) {
			return (

					ID:

						<input ref="keyOrIdInput" onFocus={this.handleKeyFocus} value={this.props.data.id} className="EditForm__key-or-id__input" readOnly />

			);
		}
	},
	renderNameField () {
		var nameField = this.props.list.nameField;
		var nameIsEditable = this.props.list.nameIsEditable;
		var wrapNameField = field => (

				{field}

		);
		if (nameIsEditable) {
			var nameFieldProps = this.getFieldProps(nameField);
			nameFieldProps.label = null;
			nameFieldProps.size = 'full';
			nameFieldProps.inputProps = {
				className: 'item-name-field',
				placeholder: nameField.label,
				size: 'lg',
			};
			return wrapNameField(
				React.createElement(Fields[nameField.type], nameFieldProps)
			);
		} else {
			return wrapNameField(

{this.props.data.name || '(no name)'}

			);
		}
	},
	renderFormElements () {
		var headings = 0;

		return this.props.list.uiElements.map((el) => {
			if (el.type === 'heading') {
				headings++;
				el.options.values = this.state.values;
				el.key = 'h-' + headings;
				return React.createElement(FormHeading, el);
			}

			if (el.type === 'field') {
				var field = this.props.list.fields[el.field];
				var props = this.getFieldProps(field);
				if (typeof Fields[field.type] !== 'function') {
					return React.createElement(InvalidFieldType, { type: field.type, path: field.path, key: field.path });
				}
				if (props.dependsOn) {
					props.currentDependencies = {};
					Object.keys(props.dependsOn).forEach(dep => {
						props.currentDependencies[dep] = this.state.values[dep];
					});
				}
				props.key = field.path;
				return React.createElement(Fields[field.type], props);
			}
		}, this);
	},
	renderFooterBar () {
		var buttons = [
			<Button
				key="save"
				type="primary"
				disabled={this.state.loading}
				onClick={() => this.updateItem()}
			>
				{this.state.loading ? (

						<Spinner type="inverted" />
						 Saving

				) : (
					'Save'
				)}
			</Button>,
		];
		buttons.push(
			<Button key="reset" onClick={this.confirmReset} type="link-cancel">
				<ResponsiveText hiddenXS="reset changes" visibleXS="reset" />
			</Button>
		);
		if (!this.props.list.nodelete) {
			buttons.push(
				<Button key="del" onClick={this.confirmDelete} type="link-delete" className="u-float-right">
					<ResponsiveText hiddenXS={`delete ${this.props.list.singular.toLowerCase()}`} visibleXS="delete" />
				</Button>
			);
		}
		return (
			<FooterBar className="EditForm__footer">
				{buttons}
			</FooterBar>
		);
	},
	renderTrackingMeta () {
		if (!this.props.list.tracking) return null;

		var elements = [];
		var data = {};

		if (this.props.list.tracking.createdAt) {
			data.createdAt = this.props.data.fields[this.props.list.tracking.createdAt];
			if (data.createdAt) {
				elements.push(
					<FormField key="createdAt" label="Created on">
						<FormInput noedit title={moment(data.createdAt).format('DD/MM/YYYY h:mm:ssa')}>{moment(data.createdAt).format('Do MMM YYYY')}</FormInput>
					</FormField>
				);
			}
		}

		if (this.props.list.tracking.createdBy) {
			data.createdBy = this.props.data.fields[this.props.list.tracking.createdBy];
			if (data.createdBy && data.createdBy.name) {
				let createdByName = getNameFromData(data.createdBy.name);
				if (createdByName) {
					elements.push(
						<FormField key="createdBy" label="Created by">
							<FormInput noedit>{data.createdBy.name.first} {data.createdBy.name.last}</FormInput>
						</FormField>
					);
				}
			}
		}

		if (this.props.list.tracking.updatedAt) {
			data.updatedAt = this.props.data.fields[this.props.list.tracking.updatedAt];
			if (data.updatedAt && (!data.createdAt || data.createdAt !== data.updatedAt)) {
				elements.push(
					<FormField key="updatedAt" label="Updated on">
						<FormInput noedit title={moment(data.updatedAt).format('DD/MM/YYYY h:mm:ssa')}>{moment(data.updatedAt).format('Do MMM YYYY')}</FormInput>
					</FormField>
				);
			}
		}

		if (this.props.list.tracking.updatedBy) {
			data.updatedBy = this.props.data.fields[this.props.list.tracking.updatedBy];
			if (data.updatedBy && data.updatedBy.name) {
				let updatedByName = getNameFromData(data.updatedBy.name);
				if (updatedByName) {
					elements.push(
						<FormField key="updatedBy" label="Updated by">
							<FormInput noedit>{data.updatedBy.name.first} {data.updatedBy.name.last}</FormInput>
						</FormField>
					);
				}
			}
		}

		return Object.keys(elements).length ? (

Meta

				{elements}

		) : null;
	},
	render () {
		return (
			<form ref="editForm" method="post" encType="multipart/form-data" className="EditForm-container">
				<Row>
					<Col lg="3/4">
						{(this.state.alerts) ? <AlertMessages alerts={this.state.alerts} /> : null}
						<Form type="horizontal" className="EditForm" component="div">
							<input type="hidden" name="action" value="updateItem" />
							<input type="hidden" name={Keystone.csrf.key} value={Keystone.csrf.value} />
							{this.renderNameField()}
							{this.renderKeyOrId()}
							{this.renderFormElements()}
							{this.renderTrackingMeta()}
						</Form>
					</Col>
					<Col lg="1/4"></Col>
				</Row>
				{this.renderFooterBar()}
				{this.state.confirmationDialog}
			</form>
		);
	},
});

module.exports = EditForm;
<commit_msg>Fix getDOMNode warning<commit_after>import React from 'react';
import { findDOMNode } from 'react-dom';
import moment from 'moment';
import {
	Button,
	Col,
	Form,
	FormField,
	FormInput,
	ResponsiveText,
	Row,
	Spinner,
} from 'elemental';

import AlertMessages from '../../../shared/AlertMessages';
import ConfirmationDialog from './../../../shared/ConfirmationDialog';
import Fields from '../../../../utils/fields';

import FormHeading from './FormHeading';
import AltText from './AltText';
import FooterBar from './FooterBar';
import InvalidFieldType from '../../../shared/InvalidFieldType';

import { deleteItem } from '../actions';

function upCase (str) {
	return str.slice(0, 1).toUpperCase() + str.substr(1).toLowerCase();
};

function getNameFromData (data) {
	if (typeof data === 'object') {
		if (typeof data.first === 'string' && typeof data.last === 'string') {
			return data.first + ' ' + data.last;
		} else if (data.id) {
			return data.id;
		}
	}
	return data;
}

var EditForm = React.createClass({
	displayName: 'EditForm',
	propTypes: {
		data: React.PropTypes.object,
		list: React.PropTypes.object,
	},
	getInitialState () {
		return {
			values: Object.assign({}, this.props.data.fields),
			confirmationDialog: null,
			loading: false,
		};
	},
	getFieldProps (field) {
		const props = Object.assign({}, field);
		const alerts = this.state.alerts;
		// Display validation errors inline
		if (alerts && alerts.error && alerts.error.error === 'validation errors') {
			if (alerts.error.detail[field.path]) {
				// NOTE: This won't work yet, as ElementalUI doesn't allow
				// passed in isValid, only invalidates via internal state.
				// PR to fix that: https://github.com/elementalui/elemental/pull/149
				props.isValid = false;
			}
		}
		props.value = this.state.values[field.path];
		props.values = this.state.values;
		props.onChange = this.handleChange;
		props.mode = 'edit';
		return props;
	},
	handleChange (event) {
		const values = Object.assign({}, this.state.values);

		values[event.path] = event.value;
		this.setState({ values });
	},
	confirmReset (event) {
		const confirmationDialog = (
			<ConfirmationDialog
				isOpen
				body={`Reset your changes to <strong>${this.props.data.name}</strong>?`}
				confirmationLabel="Reset"
				onCancel={this.removeConfirmationDialog}
				onConfirmation={this.handleReset}
			/>
		);
		event.preventDefault();
		this.setState({ confirmationDialog });
	},
	handleReset () {
		this.setState({
			values: Object.assign({}, this.props.data.fields),
			confirmationDialog: null,
		});
	},
	confirmDelete () {
		const confirmationDialog = (
			<ConfirmationDialog
				isOpen
				body={`Are you sure you want to delete <strong>${this.props.data.name}?</strong><br /><br />This cannot be undone.`}
				confirmationLabel="Delete"
				onCancel={this.removeConfirmationDialog}
				onConfirmation={this.handleDelete}
			/>
		);
		this.setState({ confirmationDialog });
	},
	handleDelete () {
		const { data, list } = this.props;
		this.props.dispatch(deleteItem(data.id, this.props.router));
	},
	handleKeyFocus () {
		const input = findDOMNode(this.refs.keyOrIdInput);
		input.select();
	},
	removeConfirmationDialog () {
		this.setState({
			confirmationDialog: null,
		});
	},
	updateItem () {
		const { data, list } = this.props;
		const editForm = this.refs.editForm;
		const formData = new FormData(editForm);

		// Clear alerts
		this.setState({
			alerts: null,
			loading: true,
		});

		list.updateItem(data.id, formData, (err, data) => {
			// TODO: implement smooth scolling
			scrollTo(0, 0); // Scroll to top
			if (err) {
				this.setState({
					alerts: {
						error: err,
					},
					loading: false,
				});
			} else {
				// Success, display success flash messages, replace values
				// TODO: Update key value
				this.setState({
					alerts: {
						success: {
							success: 'update success',
						},
					},
					values: data.fields,
					loading: false,
				});
			}
		});
	},
	renderKeyOrId () {
		var className = 'EditForm__key-or-id';
		var list = this.props.list;

		if (list.nameField && list.autokey && this.props.data[list.autokey.path]) {
			return (

					<AltText
						normal={`${upCase(list.autokey.path)}: `}
						modified="ID:"
						component="span"
						title="Press <alt> to reveal the ID"
						className="EditForm__key-or-id__label" />
					<AltText
						normal={<input ref="keyOrIdInput" onFocus={this.handleKeyFocus} value={this.props.data[list.autokey.path]} className="EditForm__key-or-id__input" readOnly />}
						modified={<input ref="keyOrIdInput" onFocus={this.handleKeyFocus} value={this.props.data.id} className="EditForm__key-or-id__input" readOnly />}
						component="span"
						title="Press <alt> to reveal the ID"
						className="EditForm__key-or-id__field" />

			);
		} else if (list.autokey && this.props.data[list.autokey.path]) {
			return (

					{list.autokey.path}:

						<input ref="keyOrIdInput" onFocus={this.handleKeyFocus} value={this.props.data[list.autokey.path]} className="EditForm__key-or-id__input" readOnly />

			);
		} else if (list.nameField) {
			return (

					ID:

						<input ref="keyOrIdInput" onFocus={this.handleKeyFocus} value={this.props.data.id} className="EditForm__key-or-id__input" readOnly />

			);
		}
	},
	renderNameField () {
		var nameField = this.props.list.nameField;
		var nameIsEditable = this.props.list.nameIsEditable;
		var wrapNameField = field => (

				{field}

		);
		if (nameIsEditable) {
			var nameFieldProps = this.getFieldProps(nameField);
			nameFieldProps.label = null;
			nameFieldProps.size = 'full';
			nameFieldProps.inputProps = {
				className: 'item-name-field',
				placeholder: nameField.label,
				size: 'lg',
			};
			return wrapNameField(
				React.createElement(Fields[nameField.type], nameFieldProps)
			);
		} else {
			return wrapNameField(

{this.props.data.name || '(no name)'}

			);
		}
	},
	renderFormElements () {
		var headings = 0;

		return this.props.list.uiElements.map((el) => {
			if (el.type === 'heading') {
				headings++;
				el.options.values = this.state.values;
				el.key = 'h-' + headings;
				return React.createElement(FormHeading, el);
			}

			if (el.type === 'field') {
				var field = this.props.list.fields[el.field];
				var props = this.getFieldProps(field);
				if (typeof Fields[field.type] !== 'function') {
					return React.createElement(InvalidFieldType, { type: field.type, path: field.path, key: field.path });
				}
				if (props.dependsOn) {
					props.currentDependencies = {};
					Object.keys(props.dependsOn).forEach(dep => {
						props.currentDependencies[dep] = this.state.values[dep];
					});
				}
				props.key = field.path;
				return React.createElement(Fields[field.type], props);
			}
		}, this);
	},
	renderFooterBar () {
		var buttons = [
			<Button
				key="save"
				type="primary"
				disabled={this.state.loading}
				onClick={() => this.updateItem()}
			>
				{this.state.loading ? (

						<Spinner type="inverted" />
						 Saving

				) : (
					'Save'
				)}
			</Button>,
		];
		buttons.push(
			<Button key="reset" onClick={this.confirmReset} type="link-cancel">
				<ResponsiveText hiddenXS="reset changes" visibleXS="reset" />
			</Button>
		);
		if (!this.props.list.nodelete) {
			buttons.push(
				<Button key="del" onClick={this.confirmDelete} type="link-delete" className="u-float-right">
					<ResponsiveText hiddenXS={`delete ${this.props.list.singular.toLowerCase()}`} visibleXS="delete" />
				</Button>
			);
		}
		return (
			<FooterBar className="EditForm__footer">
				{buttons}
			</FooterBar>
		);
	},
	renderTrackingMeta () {
		if (!this.props.list.tracking) return null;

		var elements = [];
		var data = {};

		if (this.props.list.tracking.createdAt) {
			data.createdAt = this.props.data.fields[this.props.list.tracking.createdAt];
			if (data.createdAt) {
				elements.push(
					<FormField key="createdAt" label="Created on">
						<FormInput noedit title={moment(data.createdAt).format('DD/MM/YYYY h:mm:ssa')}>{moment(data.createdAt).format('Do MMM YYYY')}</FormInput>
					</FormField>
				);
			}
		}

		if (this.props.list.tracking.createdBy) {
			data.createdBy = this.props.data.fields[this.props.list.tracking.createdBy];
			if (data.createdBy && data.createdBy.name) {
				let createdByName = getNameFromData(data.createdBy.name);
				if (createdByName) {
					elements.push(
						<FormField key="createdBy" label="Created by">
							<FormInput noedit>{data.createdBy.name.first} {data.createdBy.name.last}</FormInput>
						</FormField>
					);
				}
			}
		}

		if (this.props.list.tracking.updatedAt) {
			data.updatedAt = this.props.data.fields[this.props.list.tracking.updatedAt];
			if (data.updatedAt && (!data.createdAt || data.createdAt !== data.updatedAt)) {
				elements.push(
					<FormField key="updatedAt" label="Updated on">
						<FormInput noedit title={moment(data.updatedAt).format('DD/MM/YYYY h:mm:ssa')}>{moment(data.updatedAt).format('Do MMM YYYY')}</FormInput>
					</FormField>
				);
			}
		}

		if (this.props.list.tracking.updatedBy) {
			data.updatedBy = this.props.data.fields[this.props.list.tracking.updatedBy];
			if (data.updatedBy && data.updatedBy.name) {
				let updatedByName = getNameFromData(data.updatedBy.name);
				if (updatedByName) {
					elements.push(
						<FormField key="updatedBy" label="Updated by">
							<FormInput noedit>{data.updatedBy.name.first} {data.updatedBy.name.last}</FormInput>
						</FormField>
					);
				}
			}
		}

		return Object.keys(elements).length ? (

Meta

				{elements}

		) : null;
	},
	render () {
		return (
			<form ref="editForm" method="post" encType="multipart/form-data" className="EditForm-container">
				<Row>
					<Col lg="3/4">
						{(this.state.alerts) ? <AlertMessages alerts={this.state.alerts} /> : null}
						<Form type="horizontal" className="EditForm" component="div">
							<input type="hidden" name="action" value="updateItem" />
							<input type="hidden" name={Keystone.csrf.key} value={Keystone.csrf.value} />
							{this.renderNameField()}
							{this.renderKeyOrId()}
							{this.renderFormElements()}
							{this.renderTrackingMeta()}
						</Form>
					</Col>
					<Col lg="1/4"></Col>
				</Row>
				{this.renderFooterBar()}
				{this.state.confirmationDialog}
			</form>
		);
	},
});

module.exports = EditForm;
<|endoftext|>