<commit_before>import React from 'react'
import { types, typeKeys, randomType } from './types'
import { randomColor } from './colors'
import Block from './Block'
import { forEach,
         map,
         mapValues,
         keys,
         find,
         max,
         min,
         sum,
         uniqueId,
         toNumber,
         merge,
         omit,
         clone,
         reverse,
         sortBy,
         pickBy,
         filter,
         remove
        }
  from 'lodash'

const dic = {
  ArrowUp:    'up',
  ArrowDown:  'down',
  ArrowRight: 'right',
  ArrowLeft:  'left',
}

const newError = (message) => {
  throw message
}

const column = (x, blocks) =>
  pickBy(blocks, block => block.x === x)

const row = (y, blocks) =>
  pickBy(blocks, block => block.y === y)

const transfer = (blocks, id, x, y) => {
  let newBlocks = merge({}, blocks)
  newBlocks[id].x = x
  newBlocks[id].y = y
  return newBlocks
}

const moveOne = (blocks, id, direction) => {
  let newPosition = {x: blocks[id].x, y: blocks[id].y}
  switch (direction) {
    case 'up':
      newPosition.y--
    break
    case 'down':
      newPosition.y++
    break
    case 'left':
      newPosition.x--
    break
    case 'right':
      newPosition.x++
    break
  }
  return transfer(blocks, id, newPosition.x, newPosition.y)
}

const move = (blocks, ids, direction) => {
  ids.length
    ? forEach(ids, id => blocks = moveOne(blocks, id, direction))
    : moveOne(blocks, ids, direction)
  return blocks
}

const Tetris = React.createClass({
  getInitialState() {
    return {
      width:  16,
      height: 24,
      size:   16,
      active: [],
      score:  0,
      blocks: {},
      speed:  1000,
    }
  },

  componentDidMount() {
    this.create()
    this.fall()
    window.addEventListener('keydown', this.listen)
  },

  listen(e) {
    if (dic[e.key] !== undefined)
      this.userMove(dic[e.key])
  },

  get(ids) {
    let result = {}
    ids.length
      ? forEach(ids, id => result[id] = this.state.blocks[id])
      : result = this.state.blocks[ids]
    return merge({}, result)
  },

  set(newBlocks, active = this.state.active) {
    const blocks = merge({}, this.state.blocks, newBlocks)
    this.intersects(active, blocks)
      ? this.gameOver()
      : this.setState({active, blocks})
  },

  create(type) {
    const color     = randomColor()
    let id          = max(map(keys(this.state.blocks), key => toNumber(key))) + 1 || 1
    const newBlocks = {}
    const active    = []
    forEach(randomType(), (row, y) =>
      forEach(row, (col, x) => {
          if (col) {
            active.push(id)
            newBlocks[id] = {color, x, y, parent: 1}
            id++
          }
        }))
    this.set(newBlocks, active)
  },

  transfer(id, x, y) {
    const blocks = transfer(this.state.blocks, id, x, y)
    this.intersects(id, blocks)
      ? myError(`Coordinates [${x}, ${y}] are occupied`)
      : this.setState({blocks})
  },

  intersects(ids, blocks) {
    const intersectsOne = (id) =>
      find(omit(blocks, id), block => block.x === blocks[id].x && block.y === blocks[id].y) ? true : false
    const outOfBounds = (id) => {
      const test = blocks[id].x > this.state.width - 1 || blocks[id].x < 0 || blocks[id].y > this.state.height - 1 || blocks[id].y < 0
      return test
    }

    const intersectsMany = () => {
      let result = false
      for (let id in ids) {
        if (intersectsOne(ids[id]) || outOfBounds(ids[id])) {
          result = true
          break
        }
      }

      return result
    }

    return ids.length
      ? intersectsMany()
      : intersectsOne(ids) || outOfBounds(ids)
  },

  move(ids, direction) {
    const blocks = move(this.state.blocks, ids, direction)
    if (this.intersects(ids, blocks)) {
      return false
    } else {
      this.setState({blocks})
      return true
    }
  },

  drop(toMove = this.state.active) {
    const sortedActive = reverse(sortBy(toMove, id => this.state.blocks[id].y))

    let blocks = merge({}, this.state.blocks)

    const nextPos = (x, y) => {
      const currentColumn = map(column(x, blocks), block => block.y)
      const lower         = remove(currentColumn, n => n > y)
      return min(lower) - 1 || this.state.height - 1
    }

    forEach(sortedActive, key =>
      blocks[key].y = nextPos(blocks[key].x, blocks[key].y)
    )
    this.set(blocks)
  },

  rotate(blocksToRotate = this.state.active) {
    const blockObjs = this.get(blocksToRotate)
    const xs = map(blockObjs, block => block.x)
    const ys = map(blockObjs, block => block.y)
    const x0 = sum(xs) / xs.length //(min(xs) + max(xs)) / 2
    const y0 = sum(ys) / ys.length //(min(ys) + max(ys)) / 2

    forEach(blocksToRotate, block => {
      const {x, y} = blockObjs[block]
      blockObjs[block].x = Math.round(x0 + ((x - x0) * Math.cos(Math.PI / 2)) - ((y - y0) * Math.sin(Math.PI / 2)))
      blockObjs[block].y = Math.round(y0 + ((x - x0) * Math.sin(Math.PI / 2)) - ((y - y0) * Math.cos(Math.PI / 2)))
    })

    let blocks       = merge({}, this.state.blocks, blockObjs)
    const blockKeys  = keys(blockObjs)

    // TODO Try to move block from obstacle
    // const directions = ['left', 'right', 'top']
    //
    // const check = (blocksToCheck, i) => {
    //   if (i <= 2)
    //     this.intersects(blockKeys, blocksToCheck)
    //       ? check(move(blocks, blockKeys, directions[i] + 1), i + 1)
    //       : blocks = blocksToCheck
    // }
    //
    // check(blocks, 0)
    if (this.intersects(blockKeys, blocks) === false)
      this.set(blocks)
  },

  fall() {
    const currentFall = () => {
      this.move(this.state.active, 'down') ||
     (this.drop(),
      this.create())
    }

    this.setState({motor: window.setInterval(currentFall, this.state.speed)})
  },

  gameOver() {
    window.clearInterval(this.state.motor)
    window.removeEventListener('keydown', this.listen)
    this.setState({motor: null})
  },

  newGame() {
    this.setState({
      active: [],
      score:  0,
      blocks: {}
    })
    this.create()
    this.fall()
  },

  userMove(direction) {
    switch (direction) {
      case 'up':
        this.rotate()
      break
      case 'down':
        this.drop()
        this.resolve()
        this.create()
      break
      default:
        this.move(this.state.active, direction)
    }
  },

  resolve() {
    const lastRow = keys(row(this.state.height - 1, this.state.blocks))
    if (lastRow.length === this.state.width) {
      this.setState({blocks: omit(this.state.blocks, lastRow)})
      this.move(keys(this.state.blocks), 'down')
      this.updateScore()
      this.resolve()
    }
  },

  updateScore(by = 1) {
    this.setState({score: this.state.score + by})
  },

  render() {
    return

        {map(this.state.blocks, (block, key) =>
          <Block {...block} key={key} size={this.state.size} />)}

        {this.state.motor
          ?

{this.state.score}

← Left

→ Right

↑ Rotate

↓ Drop

          :

Game over

Score {this.state.score}

New

          }

  }
})

export default Tetris
<commit_msg>NewGame method<commit_after>import React from 'react'
import { types, typeKeys, randomType } from './types'
import { randomColor } from './colors'
import Block from './Block'
import { forEach,
         map,
         mapValues,
         keys,
         find,
         max,
         min,
         sum,
         uniqueId,
         toNumber,
         merge,
         omit,
         clone,
         reverse,
         sortBy,
         pickBy,
         filter,
         remove
        }
  from 'lodash'

const dic = {
  ArrowUp:    'up',
  ArrowDown:  'down',
  ArrowRight: 'right',
  ArrowLeft:  'left',
}

const newError = (message) => {
  throw message
}

const createFigure = (fromID = 0, color = randomColor()) => {
  let id = fromID
  let blocks = {}
  forEach(randomType(), (row, y) =>
    forEach(row, (col, x) => {
        if (col) {
          blocks[id] = {color, x, y}
          id++
        }
      }))
  return blocks
}

const column = (x, blocks) =>
  pickBy(blocks, block => block.x === x)

const row = (y, blocks) =>
  pickBy(blocks, block => block.y === y)

const transfer = (blocks, id, x, y) => {
  let newBlocks = merge({}, blocks)
  newBlocks[id].x = x
  newBlocks[id].y = y
  return newBlocks
}

const moveOne = (blocks, id, direction) => {
  let newPosition = {x: blocks[id].x, y: blocks[id].y}
  switch (direction) {
    case 'up':
      newPosition.y--
    break
    case 'down':
      newPosition.y++
    break
    case 'left':
      newPosition.x--
    break
    case 'right':
      newPosition.x++
    break
  }
  return transfer(blocks, id, newPosition.x, newPosition.y)
}

const move = (blocks, ids, direction) => {
  ids.length
    ? forEach(ids, id => blocks = moveOne(blocks, id, direction))
    : moveOne(blocks, ids, direction)
  return blocks
}

const Tetris = React.createClass({
  getInitialState() {
    return {
      width:  16,
      height: 24,
      size:   16,
      active: [],
      score:  0,
      blocks: {},
      speed:  1000,
    }
  },

  componentDidMount() {
    this.create()
    this.fall()
    window.addEventListener('keydown', this.listen)
  },

  listen(e) {
    if (dic[e.key] !== undefined)
      this.userMove(dic[e.key])
  },

  get(ids) {
    let result = {}
    ids.length
      ? forEach(ids, id => result[id] = this.state.blocks[id])
      : result = this.state.blocks[ids]
    return merge({}, result)
  },

  set(newBlocks, active = this.state.active) {
    const blocks = merge({}, this.state.blocks, newBlocks)
    this.intersects(active, blocks)
      ? this.gameOver()
      : this.setState({active, blocks})
  },

  create(type) {
    let id          = max(map(keys(this.state.blocks), key => toNumber(key))) + 1 || 1
    const newBlocks = createFigure(id)
    const active    = keys(newBlocks)
    this.set(newBlocks, active)
  },

  transfer(id, x, y) {
    const blocks = transfer(this.state.blocks, id, x, y)
    this.intersects(id, blocks)
      ? myError(`Coordinates [${x}, ${y}] are occupied`)
      : this.setState({blocks})
  },

  intersects(ids, blocks) {
    const intersectsOne = (id) =>
      find(omit(blocks, id), block => block.x === blocks[id].x && block.y === blocks[id].y) ? true : false
    const outOfBounds = (id) => {
      const test = blocks[id].x > this.state.width - 1 || blocks[id].x < 0 || blocks[id].y > this.state.height - 1 || blocks[id].y < 0
      return test
    }

    const intersectsMany = () => {
      let result = false
      for (let id in ids) {
        if (intersectsOne(ids[id]) || outOfBounds(ids[id])) {
          result = true
          break
        }
      }

      return result
    }

    return ids.length
      ? intersectsMany()
      : intersectsOne(ids) || outOfBounds(ids)
  },

  move(ids, direction) {
    const blocks = move(this.state.blocks, ids, direction)
    if (this.intersects(ids, blocks)) {
      return false
    } else {
      this.setState({blocks})
      return true
    }
  },

  drop(toMove = this.state.active) {
    const sortedActive = reverse(sortBy(toMove, id => this.state.blocks[id].y))

    let blocks = merge({}, this.state.blocks)

    const nextPos = (x, y) => {
      const currentColumn = map(column(x, blocks), block => block.y)
      const lower         = remove(currentColumn, n => n > y)
      return min(lower) - 1 || this.state.height - 1
    }

    forEach(sortedActive, key =>
      blocks[key].y = nextPos(blocks[key].x, blocks[key].y)
    )
    this.set(blocks)
  },

  rotate(blocksToRotate = this.state.active) {
    const blockObjs = this.get(blocksToRotate)
    const xs = map(blockObjs, block => block.x)
    const ys = map(blockObjs, block => block.y)
    const x0 = sum(xs) / xs.length //(min(xs) + max(xs)) / 2
    const y0 = sum(ys) / ys.length //(min(ys) + max(ys)) / 2

    forEach(blocksToRotate, block => {
      const {x, y} = blockObjs[block]
      blockObjs[block].x = Math.round(x0 + ((x - x0) * Math.cos(Math.PI / 2)) - ((y - y0) * Math.sin(Math.PI / 2)))
      blockObjs[block].y = Math.round(y0 + ((x - x0) * Math.sin(Math.PI / 2)) - ((y - y0) * Math.cos(Math.PI / 2)))
    })

    let blocks       = merge({}, this.state.blocks, blockObjs)
    const blockKeys  = keys(blockObjs)

    // TODO Try to move block from obstacle
    // const directions = ['left', 'right', 'top']
    //
    // const check = (blocksToCheck, i) => {
    //   if (i <= 2)
    //     this.intersects(blockKeys, blocksToCheck)
    //       ? check(move(blocks, blockKeys, directions[i] + 1), i + 1)
    //       : blocks = blocksToCheck
    // }
    //
    // check(blocks, 0)
    if (this.intersects(blockKeys, blocks) === false)
      this.set(blocks)
  },

  fall() {
    const currentFall = () => {
      this.move(this.state.active, 'down') ||
     (this.drop(),
      this.create())
    }

    this.setState({motor: window.setInterval(currentFall, this.state.speed)})
  },

  gameOver() {
    window.clearInterval(this.state.motor)
    window.removeEventListener('keydown', this.listen)
    this.setState({motor: null})
  },

  newGame() {
    const blocks = createFigure()
    const active = keys(blocks)
    this.setState({blocks, active, score: 0})
    window.addEventListener('keydown', this.listen)
    this.fall()

  },

  userMove(direction) {
    switch (direction) {
      case 'up':
        this.rotate()
      break
      case 'down':
        this.drop()
        this.resolve()
        this.create()
      break
      default:
        this.move(this.state.active, direction)
    }
  },

  resolve() {
    const lastRow = keys(row(this.state.height - 1, this.state.blocks))
    if (lastRow.length === this.state.width) {
      this.setState({blocks: omit(this.state.blocks, lastRow)})
      this.move(keys(this.state.blocks), 'down')
      this.updateScore()
      this.resolve()
    }
  },

  updateScore(by = 1) {
    this.setState({score: this.state.score + by})
  },

  render() {
    return

        {map(this.state.blocks, (block, key) =>
          <Block {...block} key={key} size={this.state.size} />)}

        {this.state.motor
          ?

{this.state.score}

← Left

→ Right

↑ Rotate

↓ Drop

          :

Game over

Score {this.state.score}

New

          }

  }
})

export default Tetris
<|endoftext|>


<commit_before>var acceptedPointsData = [];
var acceptedCountData = [];
var myMask = null;
var app = null;
var showAssignedProgram = true;

Ext.define('CustomApp', {
    scopeType: 'release',
    extend: 'Rally.app.App',
    componentCls: 'app',

    // switch to app configuration from ui selection
    config: {

        defaultSettings : {
            releases                : "",
            epicIds                 : "",
            ignoreZeroValues        : true,
            PreliminaryEstimate     : true,
            StoryPoints             : true,
            StoryCount              : false,
            StoryPointsProjection   : true,
            StoryCountProjection    : false,
            AcceptedStoryPoints     : true,
            AcceptedStoryCount      : false,
            AcceptedPointsProjection: true,
            AcceptedCountProjection : false,
            FeatureCount            : false,
            FeatureCountCompleted   : false,
            HistoricalProjection    : false,
            RefinedEstimate : false
        }

    },

    getSettingsFields: function() {

        var checkValues = _.map(createSeriesArray(),function(s) {
            return { name : s.name, xtype : 'rallycheckboxfield', label : s.description};
        });

        var values = [
            {
                name: 'releases',
                xtype: 'rallytextfield',
                label : "Release names to be included (comma seperated)"
            },
            {
                name: 'epicIds',
                xtype: 'rallytextfield',
                label : "(Optional) List of Parent PortfolioItem (Epics) ids to filter Features by"
            },

            {
                name: 'ignoreZeroValues',
                xtype: 'rallycheckboxfield',
                label: 'For projection ignore zero values'
            }
        ];

        _.each(values,function(value){
            value.labelWidth = 250;
            value.labelAlign = 'left'
        });

        return values.concat(checkValues);
    },

    launch: function() {

        app = this;
        app.series = createSeriesArray();
        app.configReleases = app.getSetting("releases");
        app.ignoreZeroValues = app.getSetting("ignoreZeroValues");
        app.epicIds = app.getSetting("epicIds");

        if (app.configReleases==="") {
            this.add({html:"Please Configure this app by selecting Edit App Settings from Configure (gear) Menu"});
            return;
        }

        var that = this;
        // get the project id.
        this.project = this.getContext().getProject().ObjectID;

        // get the release (if on a page scoped to the release)
        var tbName = getReleaseTimeBox(this);
        // release selected page will over-ride app config
        app.configReleases = tbName !== "" ? tbName : app.configReleases;

        var configs = [];

        // query for estimate values, releases and iterations.
        configs.push({ model : "PreliminaryEstimate",
                       fetch : ['Name','ObjectID','Value'],
                       filters : []
        });
        configs.push({ model : "Release",
                       fetch : ['Name', 'ObjectID', 'Project', 'ReleaseStartDate', 'ReleaseDate' ],
                       filters: [app.createReleaseFilter(app.configReleases)]
        });
        configs.push({ model : "TypeDefinition",
                       fetch : true,
                       filters : [ { property:"Ordinal", operator:"=", value:0} ]
        });

        // get the preliminary estimate type values, and the releases.
        async.map( configs, app.wsapiQuery, function(err,results) {

            app.peRecords   = results[0];
            app.releases    = results[1];
            app.featureType = results[2][0].get("TypePath");

            if (app.releases.length===0) {
                app.add({html:"No Releases found with this name: "+app.configReleases});
                return;
            }

            configs = [
                {
                    model  : "Iteration",
                    fetch  : ['Name', 'ObjectID', 'Project', 'StartDate', 'EndDate' ],
                    filters: app.createIterationFilter(app.releases)
                }
            ];

            // get the iterations
            async.map( configs, app.wsapiQuery, function(err,results) {

                app.iterations = results[0];

                if (app.epicIds.split(",")[0] !=="")
                    app.queryEpicFeatures();
                else
                    app.queryFeatures();

            });
        });
    },

    // remove leading and trailing spaces
    trimString : function (str) {
        return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
    },

    // creates a filter to return all releases with a specified set of names
    createReleaseFilter : function(releaseNames) {

        var filter = null;

        _.each( releaseNames.split(","), function( releaseName, i ) {
            if (releaseName !== "") {
                var f = Ext.create('Rally.data.wsapi.Filter', {
                        property : 'Name', operator : '=', value : app.trimString(releaseName) }
                );
                filter = (i===0) ? f : filter.or(f);
            }
        });

        console.log("Release Filter:",filter.toString());
        return filter;

    },

    createIterationFilter : function(releases) {

        var extent = app.getReleaseExtent(releases);

        var filter = Ext.create('Rally.data.wsapi.Filter', {
            property : 'EndDate', operator: ">=", value: extent.isoStart
        });

        filter = filter.and( Ext.create('Rally.data.wsapi.Filter', {
                property : 'EndDate', operator: "<=", value: extent.isoEnd
            })
        );

        return filter;
    },

    getReleaseExtent : function( releases ) {

        var start = _.min(_.pluck(releases,function(r) { return r.get("ReleaseStartDate");}));
        var end   = _.max(_.pluck(releases,function(r) { return r.get("ReleaseDate");}));
        var isoStart  = Rally.util.DateTime.toIsoString(start, false);
        var isoEnd    = Rally.util.DateTime.toIsoString(end, false);

        return { start : start, end : end, isoStart : isoStart, isoEnd : isoEnd };

    },

    // generic function to perform a web services query
    wsapiQuery : function( config , callback ) {

        Ext.create('Rally.data.WsapiDataStore', {
            autoLoad : true,
            limit : "Infinity",
            model : config.model,
            fetch : config.fetch,
            filters : config.filters,
            listeners : {
                scope : this,
                load : function(store, data) {
                    callback(null,data);
                }
            }
        });

    },

    queryEpicFeatures : function() {

        myMask = new Ext.LoadMask(Ext.getBody(), {msg:"Please wait..."});

        var filter = null;
        var epicIds = app.epicIds.split(",");

        if (epicIds.length === 0) {
            app.add({html:"No epic id's specified"+app.configReleases});
            return;
        }

        _.each(epicIds, function( epicId, i) {
            var f = Ext.create('Rally.data.QueryFilter', {
                property: 'Parent.FormattedID',
                operator: '=',
                value: epicId
            });
            filter = i === 0 ? f : filter.or(f);
        });

        return Ext.create('Rally.data.WsapiDataStore', {
            autoLoad: true,
            model : app.featureType,
            limit : 'Infinity',
            fetch: ['ObjectID','FormattedID' ],
            filters: [filter],
            listeners: {
                load: function(store, features) {
                    console.log("Loaded:"+features.length," Features.");
                    app.features = features;
                    if (app.features.length === 0) {
                        app.add({html:"No features for parent PortfolioItem :"+app.epicIds});
                        return;
                    } else {
                    app.queryFeatureSnapshots();
                    }
                }
            }
        });

    },

    queryFeatures : function() {

        myMask = new Ext.LoadMask(Ext.getBody(), {msg:"Please wait..."});
        var filter = null;

        var releaseNames = _.uniq(_.map(app.releases,function(r){ return r.get("Name");}));
        console.log("releaseNames",releaseNames);

        _.each( releaseNames , function( release, i ) {
            var f = Ext.create('Rally.data.QueryFilter', {
                property: 'Release.Name',
                operator: '=',
                value: release
            });
            filter = i === 0 ? f : filter.or(f);
        });

        return Ext.create('Rally.data.WsapiDataStore', {
            autoLoad: true,
//            model: 'PortfolioItem/Feature',
            model : app.featureType,
            limit : 'Infinity',
            fetch: ['ObjectID','FormattedID' ],
            filters: [filter],
            listeners: {
                load: function(store, features) {
                    console.log("Loaded:"+features.length," Features.");
                    app.features = features;
                    if (app.features.length === 0) {
                        app.add({html:"No features in release(s):"+app.configReleases});
                        return;
                    } else {
                    app.queryFeatureSnapshots();
                    }
                }
            }
        });
    },

    queryFeatureSnapshots : function () {

        var ids = _.pluck(app.features, function(feature) { return feature.get("ObjectID");} );
        // var pes = _.pluck(app.features, function(feature) { return feature.get("PreliminaryEstimate");} );
        var extent = app.getReleaseExtent(app.releases);
        // console.log("ids",ids,pes);

        var storeConfig = {
            find : {
                // '_TypeHierarchy' : { "$in" : ["PortfolioItem/PIFTeam"] },
                'ObjectID' : { "$in" : ids },
                '_ValidTo' : { "$gte" : extent.isoStart }
            },
            autoLoad : true,
            pageSize:1000,
            limit: 'Infinity',
            fetch: ['_UnformattedID','ObjectID','_TypeHierarchy','PreliminaryEstimate', 'LeafStoryCount','LeafStoryPlanEstimateTotal','AcceptedLeafStoryPlanEstimateTotal','AcceptedLeafStoryCount','PercentDoneByStoryCount','RefinedEstimate'],
            hydrate: ['_TypeHierarchy']
        };

        storeConfig.listeners = {
            scope : this,
            load: function(store, snapshots, success) {
                console.log("Loaded:"+snapshots.length," Snapshots.");
                app.createChartData(snapshots);
            }
        };

        var snapshotStore = Ext.create('Rally.data.lookback.SnapshotStore', storeConfig);
    },

    createChartData : function ( snapshots ) {

        var that = this;
        var lumenize = window.parent.Rally.data.lookback.Lumenize;
        var snapShotData = _.map(snapshots,function(d){return d.data;});
        var extent = app.getReleaseExtent(app.releases);

        var snaps = _.sortBy(snapShotData,"_UnformattedID");
        // can be used to 'knockout' holidays
        var holidays = [
            //{year: 2014, month: 1, day: 1}  // Made up holiday to test knockout
        ];

        var myCalc = Ext.create("MyBurnCalculator", {
            series : app.series,
            ignoreZeroValues : app.ignoreZeroValues,
            peRecords : app.peRecords
        });

        // calculator config
        var config = {
            deriveFieldsOnInput: myCalc.getDerivedFieldsOnInput(),
            metrics: myCalc.getMetrics(),
            summaryMetricsConfig: [],
            deriveFieldsAfterSummary: myCalc.getDerivedFieldsAfterSummary(),
            granularity: lumenize.Time.DAY,
            tz: 'America/Chicago',
            holidays: holidays,
            workDays: 'Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday'
        };
        // release start and end dates
        var startOnISOString = new lumenize.Time(extent.start).getISOStringInTZ(config.tz);
        var upToDateISOString = new lumenize.Time(extent.end).getISOStringInTZ(config.tz);
        // create the calculator and add snapshots to it.
        calculator = new lumenize.TimeSeriesCalculator(config);
        calculator.addSnapshots(snapShotData, startOnISOString, upToDateISOString);

        // create a high charts series config object, used to get the hc series data
        var hcConfig = [{ name : "label" }];
        _.each( app.series, function(s) {
            if ( app.getSetting(s.name)===true) {
                hcConfig.push({
                   name : s.description, type : s.display
                });
            }
        });
        var hc = lumenize.arrayOfMaps_To_HighChartsSeries(calculator.getResults().seriesData, hcConfig);
        this.showChart( trimHighChartsConfig(hc) );
    },

    createPlotLines : function(seriesData) {

        // filter the iterations
        var start = new Date( Date.parse(seriesData[0]));
        var end   = new Date( Date.parse(seriesData[seriesData.length-1]));
        var releaseI = _.filter(this.iterations,function(i) { return i.get("EndDate") >= start && i.get("EndDate") <= end;});
        releaseI = _.uniq(releaseI,function(i) { return i.get("Name");});
        var itPlotLines = _.map(releaseI, function(i){
            var d = new Date(Date.parse(i.raw.EndDate)).toISOString().split("T")[0];
            return {
                label : i.get("Name"),
                dashStyle : "Dot",
                color: 'grey',
                width: 1,
                value: _.indexOf(seriesData,d)
            };
        });
        // create release plot lines
        var rePlotLines = _.map(this.selectedReleases, function(i){
            var d = new Date(Date.parse(i.raw.ReleaseDate)).toISOString().split("T")[0];
            return {
                label : i.get("Name"),
                // dashStyle : "Dot",
                color: 'grey',
                width: 1,
                value: _.indexOf(seriesData,d)
            };
        });
        return itPlotLines.concat(rePlotLines);

    },

    showChart : function(series) {

        var that = this;

        // console.log("series",series);
        // console.log("Last Accepted Projection  ",_.last(series[5].data));
        // console.log("Last Historical Projection",_.last(series[6].data));

        var chart = this.down("#chart1");
        myMask.hide();
        if (chart !== null)
            chart.removeAll();

        // create plotlines
        var plotlines = this.createPlotLines(series[0].data);

        // set the tick interval
        var tickInterval = series[1].data.length <= (7*20) ? 7 : (series[1].data.length / 20);

        var extChart = Ext.create('Rally.ui.chart.Chart', {
            columnWidth : 1,
            itemId : "chart1",
            chartData: {
                categories : series[0].data,
                series : series.slice(1, series.length)
            },

            chartColors : createColorsArray(series),

            chartConfig : {
                chart: {
                },
                title: {
                text: 'PSI Feature Burnup ('+ app.configReleases  +')',
                x: -20 //center
                },
                plotOptions: {
                    series: {
                        marker: {
                            radius: 2
                        }
                    }
                },
                xAxis: {
                    plotLines : plotlines,
                    //tickInterval : 7,
                    tickInterval : tickInterval,
                    type: 'datetime',
                    labels: {
                        formatter: function() {
                            return Highcharts.dateFormat('%b %d', Date.parse(this.value));
                        }
                    }
                },
                yAxis: {
                    title: {
                        text : 'Points/Count'
                    },
                    plotLines: [{
                        value: 0,
                        width: 1,
                        color: '#808080'
                    }]
                },
                tooltip: {
                },
                legend: { align: 'center', verticalAlign: 'bottom' }
            }
        });
        this.add(extChart);
        chart = this.down("#chart1");
        var p = Ext.get(chart.id);
        elems = p.query("div.x-mask");
        _.each(elems, function(e) { e.remove(); });
        var elems = p.query("div.x-mask-msg");
        _.each(elems, function(e) { e.remove(); });

    }

});
<commit_msg>fixed lumenize reference<commit_after>var acceptedPointsData = [];
var acceptedCountData = [];
var myMask = null;
var app = null;
var showAssignedProgram = true;

Ext.define('CustomApp', {
    scopeType: 'release',
    extend: 'Rally.app.App',
    componentCls: 'app',

    // switch to app configuration from ui selection
    config: {

        defaultSettings : {
            releases                : "",
            epicIds                 : "",
            ignoreZeroValues        : true,
            PreliminaryEstimate     : true,
            StoryPoints             : true,
            StoryCount              : false,
            StoryPointsProjection   : true,
            StoryCountProjection    : false,
            AcceptedStoryPoints     : true,
            AcceptedStoryCount      : false,
            AcceptedPointsProjection: true,
            AcceptedCountProjection : false,
            FeatureCount            : false,
            FeatureCountCompleted   : false,
            HistoricalProjection    : false,
            RefinedEstimate : false
        }

    },

    getSettingsFields: function() {

        var checkValues = _.map(createSeriesArray(),function(s) {
            return { name : s.name, xtype : 'rallycheckboxfield', label : s.description};
        });

        var values = [
            {
                name: 'releases',
                xtype: 'rallytextfield',
                label : "Release names to be included (comma seperated)"
            },
            {
                name: 'epicIds',
                xtype: 'rallytextfield',
                label : "(Optional) List of Parent PortfolioItem (Epics) ids to filter Features by"
            },

            {
                name: 'ignoreZeroValues',
                xtype: 'rallycheckboxfield',
                label: 'For projection ignore zero values'
            }
        ];

        _.each(values,function(value){
            value.labelWidth = 250;
            value.labelAlign = 'left'
        });

        return values.concat(checkValues);
    },

    launch: function() {

        app = this;
        app.series = createSeriesArray();
        app.configReleases = app.getSetting("releases");
        app.ignoreZeroValues = app.getSetting("ignoreZeroValues");
        app.epicIds = app.getSetting("epicIds");

        if (app.configReleases==="") {
            this.add({html:"Please Configure this app by selecting Edit App Settings from Configure (gear) Menu"});
            return;
        }

        var that = this;
        // get the project id.
        this.project = this.getContext().getProject().ObjectID;

        // get the release (if on a page scoped to the release)
        var tbName = getReleaseTimeBox(this);
        // release selected page will over-ride app config
        app.configReleases = tbName !== "" ? tbName : app.configReleases;

        var configs = [];

        // query for estimate values, releases and iterations.
        configs.push({ model : "PreliminaryEstimate",
                       fetch : ['Name','ObjectID','Value'],
                       filters : []
        });
        configs.push({ model : "Release",
                       fetch : ['Name', 'ObjectID', 'Project', 'ReleaseStartDate', 'ReleaseDate' ],
                       filters: [app.createReleaseFilter(app.configReleases)]
        });
        configs.push({ model : "TypeDefinition",
                       fetch : true,
                       filters : [ { property:"Ordinal", operator:"=", value:0} ]
        });

        // get the preliminary estimate type values, and the releases.
        async.map( configs, app.wsapiQuery, function(err,results) {

            app.peRecords   = results[0];
            app.releases    = results[1];
            app.featureType = results[2][0].get("TypePath");

            if (app.releases.length===0) {
                app.add({html:"No Releases found with this name: "+app.configReleases});
                return;
            }

            configs = [
                {
                    model  : "Iteration",
                    fetch  : ['Name', 'ObjectID', 'Project', 'StartDate', 'EndDate' ],
                    filters: app.createIterationFilter(app.releases)
                }
            ];

            // get the iterations
            async.map( configs, app.wsapiQuery, function(err,results) {

                app.iterations = results[0];

                if (app.epicIds.split(",")[0] !=="")
                    app.queryEpicFeatures();
                else
                    app.queryFeatures();

            });
        });
    },

    // remove leading and trailing spaces
    trimString : function (str) {
        return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
    },

    // creates a filter to return all releases with a specified set of names
    createReleaseFilter : function(releaseNames) {

        var filter = null;

        _.each( releaseNames.split(","), function( releaseName, i ) {
            if (releaseName !== "") {
                var f = Ext.create('Rally.data.wsapi.Filter', {
                        property : 'Name', operator : '=', value : app.trimString(releaseName) }
                );
                filter = (i===0) ? f : filter.or(f);
            }
        });

        console.log("Release Filter:",filter.toString());
        return filter;

    },

    createIterationFilter : function(releases) {

        var extent = app.getReleaseExtent(releases);

        var filter = Ext.create('Rally.data.wsapi.Filter', {
            property : 'EndDate', operator: ">=", value: extent.isoStart
        });

        filter = filter.and( Ext.create('Rally.data.wsapi.Filter', {
                property : 'EndDate', operator: "<=", value: extent.isoEnd
            })
        );

        return filter;
    },

    getReleaseExtent : function( releases ) {

        var start = _.min(_.pluck(releases,function(r) { return r.get("ReleaseStartDate");}));
        var end   = _.max(_.pluck(releases,function(r) { return r.get("ReleaseDate");}));
        var isoStart  = Rally.util.DateTime.toIsoString(start, false);
        var isoEnd    = Rally.util.DateTime.toIsoString(end, false);

        return { start : start, end : end, isoStart : isoStart, isoEnd : isoEnd };

    },

    // generic function to perform a web services query
    wsapiQuery : function( config , callback ) {

        Ext.create('Rally.data.WsapiDataStore', {
            autoLoad : true,
            limit : "Infinity",
            model : config.model,
            fetch : config.fetch,
            filters : config.filters,
            listeners : {
                scope : this,
                load : function(store, data) {
                    callback(null,data);
                }
            }
        });

    },

    queryEpicFeatures : function() {

        myMask = new Ext.LoadMask(Ext.getBody(), {msg:"Please wait..."});

        var filter = null;
        var epicIds = app.epicIds.split(",");

        if (epicIds.length === 0) {
            app.add({html:"No epic id's specified"+app.configReleases});
            return;
        }

        _.each(epicIds, function( epicId, i) {
            var f = Ext.create('Rally.data.QueryFilter', {
                property: 'Parent.FormattedID',
                operator: '=',
                value: epicId
            });
            filter = i === 0 ? f : filter.or(f);
        });

        return Ext.create('Rally.data.WsapiDataStore', {
            autoLoad: true,
            model : app.featureType,
            limit : 'Infinity',
            fetch: ['ObjectID','FormattedID' ],
            filters: [filter],
            listeners: {
                load: function(store, features) {
                    console.log("Loaded:"+features.length," Features.");
                    app.features = features;
                    if (app.features.length === 0) {
                        app.add({html:"No features for parent PortfolioItem :"+app.epicIds});
                        return;
                    } else {
                    app.queryFeatureSnapshots();
                    }
                }
            }
        });

    },

    queryFeatures : function() {

        myMask = new Ext.LoadMask(Ext.getBody(), {msg:"Please wait..."});
        var filter = null;

        var releaseNames = _.uniq(_.map(app.releases,function(r){ return r.get("Name");}));
        console.log("releaseNames",releaseNames);

        _.each( releaseNames , function( release, i ) {
            var f = Ext.create('Rally.data.QueryFilter', {
                property: 'Release.Name',
                operator: '=',
                value: release
            });
            filter = i === 0 ? f : filter.or(f);
        });

        return Ext.create('Rally.data.WsapiDataStore', {
            autoLoad: true,
//            model: 'PortfolioItem/Feature',
            model : app.featureType,
            limit : 'Infinity',
            fetch: ['ObjectID','FormattedID' ],
            filters: [filter],
            listeners: {
                load: function(store, features) {
                    console.log("Loaded:"+features.length," Features.");
                    app.features = features;
                    if (app.features.length === 0) {
                        app.add({html:"No features in release(s):"+app.configReleases});
                        return;
                    } else {
                    app.queryFeatureSnapshots();
                    }
                }
            }
        });
    },

    queryFeatureSnapshots : function () {

        var ids = _.pluck(app.features, function(feature) { return feature.get("ObjectID");} );
        // var pes = _.pluck(app.features, function(feature) { return feature.get("PreliminaryEstimate");} );
        var extent = app.getReleaseExtent(app.releases);
        // console.log("ids",ids,pes);

        var storeConfig = {
            find : {
                // '_TypeHierarchy' : { "$in" : ["PortfolioItem/PIFTeam"] },
                'ObjectID' : { "$in" : ids },
                '_ValidTo' : { "$gte" : extent.isoStart }
            },
            autoLoad : true,
            pageSize:1000,
            limit: 'Infinity',
            fetch: ['_UnformattedID','ObjectID','_TypeHierarchy','PreliminaryEstimate', 'LeafStoryCount','LeafStoryPlanEstimateTotal','AcceptedLeafStoryPlanEstimateTotal','AcceptedLeafStoryCount','PercentDoneByStoryCount','RefinedEstimate'],
            hydrate: ['_TypeHierarchy']
        };

        storeConfig.listeners = {
            scope : this,
            load: function(store, snapshots, success) {
                console.log("Loaded:"+snapshots.length," Snapshots.");
                app.createChartData(snapshots);
            }
        };

        var snapshotStore = Ext.create('Rally.data.lookback.SnapshotStore', storeConfig);
    },

    createChartData : function ( snapshots ) {

        var that = this;
        var lumenize = window.Rally.data.lookback.Lumenize || window.parent.Rally.data.lookback.Lumenize;
        var snapShotData = _.map(snapshots,function(d){return d.data;});
        var extent = app.getReleaseExtent(app.releases);

        var snaps = _.sortBy(snapShotData,"_UnformattedID");
        // can be used to 'knockout' holidays
        var holidays = [
            //{year: 2014, month: 1, day: 1}  // Made up holiday to test knockout
        ];

        var myCalc = Ext.create("MyBurnCalculator", {
            series : app.series,
            ignoreZeroValues : app.ignoreZeroValues,
            peRecords : app.peRecords
        });

        // calculator config
        var config = {
            deriveFieldsOnInput: myCalc.getDerivedFieldsOnInput(),
            metrics: myCalc.getMetrics(),
            summaryMetricsConfig: [],
            deriveFieldsAfterSummary: myCalc.getDerivedFieldsAfterSummary(),
            granularity: lumenize.Time.DAY,
            tz: 'America/Chicago',
            holidays: holidays,
            workDays: 'Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday'
        };
        // release start and end dates
        var startOnISOString = new lumenize.Time(extent.start).getISOStringInTZ(config.tz);
        var upToDateISOString = new lumenize.Time(extent.end).getISOStringInTZ(config.tz);
        // create the calculator and add snapshots to it.
        calculator = new lumenize.TimeSeriesCalculator(config);
        calculator.addSnapshots(snapShotData, startOnISOString, upToDateISOString);

        // create a high charts series config object, used to get the hc series data
        var hcConfig = [{ name : "label" }];
        _.each( app.series, function(s) {
            if ( app.getSetting(s.name)===true) {
                hcConfig.push({
                   name : s.description, type : s.display
                });
            }
        });
        var hc = lumenize.arrayOfMaps_To_HighChartsSeries(calculator.getResults().seriesData, hcConfig);
        this.showChart( trimHighChartsConfig(hc) );
    },

    createPlotLines : function(seriesData) {

        // filter the iterations
        var start = new Date( Date.parse(seriesData[0]));
        var end   = new Date( Date.parse(seriesData[seriesData.length-1]));
        var releaseI = _.filter(this.iterations,function(i) { return i.get("EndDate") >= start && i.get("EndDate") <= end;});
        releaseI = _.uniq(releaseI,function(i) { return i.get("Name");});
        var itPlotLines = _.map(releaseI, function(i){
            var d = new Date(Date.parse(i.raw.EndDate)).toISOString().split("T")[0];
            return {
                label : i.get("Name"),
                dashStyle : "Dot",
                color: 'grey',
                width: 1,
                value: _.indexOf(seriesData,d)
            };
        });
        // create release plot lines
        var rePlotLines = _.map(this.selectedReleases, function(i){
            var d = new Date(Date.parse(i.raw.ReleaseDate)).toISOString().split("T")[0];
            return {
                label : i.get("Name"),
                // dashStyle : "Dot",
                color: 'grey',
                width: 1,
                value: _.indexOf(seriesData,d)
            };
        });
        return itPlotLines.concat(rePlotLines);

    },

    showChart : function(series) {

        var that = this;

        // console.log("series",series);
        // console.log("Last Accepted Projection  ",_.last(series[5].data));
        // console.log("Last Historical Projection",_.last(series[6].data));

        var chart = this.down("#chart1");
        myMask.hide();
        if (chart !== null)
            chart.removeAll();

        // create plotlines
        var plotlines = this.createPlotLines(series[0].data);

        // set the tick interval
        var tickInterval = series[1].data.length <= (7*20) ? 7 : (series[1].data.length / 20);

        var extChart = Ext.create('Rally.ui.chart.Chart', {
            columnWidth : 1,
            itemId : "chart1",
            chartData: {
                categories : series[0].data,
                series : series.slice(1, series.length)
            },

            chartColors : createColorsArray(series),

            chartConfig : {
                chart: {
                },
                title: {
                text: 'PSI Feature Burnup ('+ app.configReleases  +')',
                x: -20 //center
                },
                plotOptions: {
                    series: {
                        marker: {
                            radius: 2
                        }
                    }
                },
                xAxis: {
                    plotLines : plotlines,
                    //tickInterval : 7,
                    tickInterval : tickInterval,
                    type: 'datetime',
                    labels: {
                        formatter: function() {
                            return Highcharts.dateFormat('%b %d', Date.parse(this.value));
                        }
                    }
                },
                yAxis: {
                    title: {
                        text : 'Points/Count'
                    },
                    plotLines: [{
                        value: 0,
                        width: 1,
                        color: '#808080'
                    }]
                },
                tooltip: {
                },
                legend: { align: 'center', verticalAlign: 'bottom' }
            }
        });
        this.add(extChart);
        chart = this.down("#chart1");
        var p = Ext.get(chart.id);
        elems = p.query("div.x-mask");
        _.each(elems, function(e) { e.remove(); });
        var elems = p.query("div.x-mask-msg");
        _.each(elems, function(e) { e.remove(); });

    }

});
<|endoftext|>


<commit_before><<<<<<< HEAD
import React, {Component} from 'react';
import {deepOrange500} from 'material-ui/styles/colors';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';

import Host from './Host.js';

const muiTheme = getMuiTheme({
  palette: {
    accent1Color: deepOrange500,
  },
});

class App extends Component {
  constructor(props, context) {
    super(props, context);
    this.state = {
      open: false,
    };
  }

  render() {
    return (
      <MuiThemeProvider muiTheme={muiTheme}>

          <Host/>
=======
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import { Link } from 'react-router-dom';
import io from 'socket.io-client';

class App extends Component {

  componentDidMount() {
    console.log("componentDidMount <App />");
    this.ws = io.connect('ws://localhost:4000');
    this.ws.emit('event', function(data) {
      console.log("Hello");
    });
  };

  componentWillUnmount() {
    console.log('Closing socket connection');
    this.ws.close();
  };

  render() {
    return (

Welcome to React

>>>>>>> 86711b17071889c864398c83c592597f9d8cf65f

          HOSTS PAGE

          <Link to="/host">Host Page</Link>

          <Link to="/users">Users Page</Link>

    );
  }
};

export default App;<commit_msg>removed old files<commit_after>import React, {Component} from 'react';
import {deepOrange500} from 'material-ui/styles/colors';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';

import Host from './Host.js';

const muiTheme = getMuiTheme({
  palette: {
    accent1Color: deepOrange500,
  },
});

class App extends Component {
  constructor(props, context) {
    super(props, context);
    this.state = {
      open: false,
    };
  }
  render() {
    return (
      <MuiThemeProvider muiTheme={muiTheme}>

          <Host/>

      </MuiThemeProvider>
    );
  }
}

export default App;
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import {
  BrowserRouter as Router,
  Route,
  Link
} from 'react-router-dom';
import { Container } from 'semantic-ui-react'

import Nav from './components/Nav';

import Messages from './containers/Messages';
import About from './containers/About';

import './App.css';

class App extends Component {
  render() {
    return (
      <Router>
        <Container fluid className="App">
          <Nav />

          <Route exact path="/" component={Messages} />
          <Route path="/messages" component={Messages} />
          <Route path="/about" component={About} />
        </Container>
      </Router>
    );
  }
}

export default App;
<commit_msg>Hide nav<commit_after>import React, { Component } from 'react';
import {
  BrowserRouter as Router,
  Route,
  Link
} from 'react-router-dom';
import { Container } from 'semantic-ui-react'

import Nav from './components/Nav';

import Messages from './containers/Messages';
import About from './containers/About';

import './App.css';

class App extends Component {
  render() {
    return (
      <Router>
        <Container fluid className="App">
          {/* <Nav /> */}

          <Route exact path="/" component={Messages} />
          <Route path="/messages" component={Messages} />
          <Route path="/about" component={About} />
        </Container>
      </Router>
    );
  }
}

export default App;
<|endoftext|>


<commit_before>import React, {Component} from 'react';
import firebase from './firebase'
import SignIn from './SignIn'
import NavBar from './NavBar'
import UserCards from './UserCards'

class App extends Component {
  constructor() {
    super()
    this.state = {
      user: null,
      userCards: [{id: 123, fullName: 'BG'}, {id:420, fullName:'RB'}]
    }
}

  render() {
    const { user } = this.state;
    // if (user) {};
    return (

        <NavBar /* will need username and logout */ />
        <UserCards userCards={this.state.userCards} />

Remembr

            <SignIn />

    );
  }
}

export default App;
<commit_msg>New Contact kinda works.<commit_after>import React, {Component} from 'react';
import firebase from './firebase'
import SignIn from './SignIn'
import NavBar from './NavBar'
import UserCards from './UserCards'
import NewContact from './NewContact'

class App extends Component {
  constructor() {
    super()
    this.state = {
      user: null,
      userCards: [{id: 123, fullName: 'BG'}, {id:420, fullName:'RB'}]
    }
}

  render() {
    const { user } = this.state;
    // if (user) {};
    return (

        <NavBar /* will need username and logout */ />
        <UserCards userCards={this.state.userCards} />
        <NewContact />

Remembr

            <SignIn />

    );
  }
}

export default App;
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import {
  BrowserRouter as Router,
  Route,
  Switch,
  Redirect
} from 'react-router-dom';
import Headroom from 'react-headroom';
import './App.css';
import Feed from './components/Feed';
import { connect } from 'react-redux';
import { checkForToken } from './actions';
import { Login } from './components/Login';

const Routes = (
  <Switch>
    <Route exact path="/feed" render={() => <Feed />} />
    <Route exact path="/" render={() => <Login />} />
    {/*<Route path="/auth" render={() => <Auth />}/>*/}
    <Redirect to="/" />
  </Switch>
);

class App extends Component {

  componentDidMount() {
    this.props.checkForToken();
  }

  render() {
    return (
      <Router>

          <Headroom style={{ backgroundColor: 'lightgrey'}}>

Tableau

          </Headroom>

            {Routes}

      </Router>
    );
  }
}

export default connect(
  state => ({ user: state.user }),
  dispatch => ({
    checkForToken() { dispatch(checkForToken()); }
  })
)(App);
<commit_msg>add footer<commit_after>import React, { Component } from 'react';
import {
  BrowserRouter as Router,
  Route,
  Switch,
  Redirect
} from 'react-router-dom';
import Headroom from 'react-headroom';
import './App.css';
import Feed from './components/Feed';
import { connect } from 'react-redux';
import { checkForToken } from './actions';
import { Login } from './components/Login';
import styled from 'styled-components';

const Footer = styled.footer`
  text-align: center;
  color: lightgrey;
  margin: 3em 0;
`;

const Routes = (
  <Switch>
    <Route exact path="/feed" render={() => <Feed />} />
    <Route exact path="/" render={() => <Login />} />
    {/*<Route path="/auth" render={() => <Auth />}/>*/}
    <Redirect to="/" />
  </Switch>
);

class App extends Component {

  componentDidMount() {
    this.props.checkForToken();
  }

  render() {
    return (
      <Router>

          <Headroom style={{ backgroundColor: 'lightgrey'}}>

Tableau

          </Headroom>

            {Routes}

            © Tableau 2017

      </Router>
    );
  }
}

export default connect(
  state => ({ user: state.user }),
  dispatch => ({
    checkForToken() { dispatch(checkForToken()); }
  })
)(App);
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import LoginRegisterBlock from './components/LoginRegisterBlock.js';
import Header from './components/Header.js';
import MenuAside from './components/MenuAside.js';
import BodyToolBar from './components/BodyToolBar.js';
import BodyContent from './components/BodyContent.js';
import UserInfoCard from './components/UserInfoCard.js';
import NotifyBox from './components/NotifyBox.js';
import Helper from './helper.js';
import uniqid from 'uniqid';

class App extends Component {
  constructor() {
    super();
    this.state = {
      isLogin: false,
      header: {
        linkActiveIndex: 0,
        userMenuActiveIndex: -1,
      },
      menuAside: {
        buttonActiveIndex: 0,
      },
      bodyToolBar: {
        buttonActiveIndex: -1,
        searchInfo: '',
      },
      bodyContent: {
        allLists: [],
        activeLists: [],
        listCheckedIds: [],
        bodyTitleIds: [],
        currentDir: '全部文件',
        currentDirId: 'root',
        sortStatus: {
          'title': -1, // -1 unsorted, 0 ascend, 1 descend
          'size': -1,
          'updatedAt': -1,
        },
      }
    };
  }

  componentDidMount() {
    Helper.isLogin((state) => this.handleLoginStateChange(state));
  }

  getItemList() {
    const bodyContent = this.state.bodyContent;
    const menuAside = this.state.menuAside;
    let activeLists = [];
    let allLists = [];

    let fetchLink = 'http://localhost:3001/';
    if (menuAside.buttonActiveIndex === 5 && bodyContent.bodyTitleIds.length === 1) {
      fetchLink += 'getTrashItemList';
    } else {
      fetchLink += 'getItemList/' + bodyContent.currentDirId;
    }

    console.log(fetchLink);
    fetch(fetchLink, {
      method: 'GET',
      credentials: 'include',
    }).then((response) => response.json())
      .then((json) => {
        if (json.success === '1' || json.success === 1) {
          const data = json.data;
          // console.log(bodyContent.activeLists);
          data.map((obj) => {
            obj.isEdit = false;
            allLists.push(obj);
            activeLists.push(obj);
          });

          bodyContent.listCheckedIds = [];
          bodyContent.sortStatus = {
            'title': -1, // -1 unsorted, 0 ascend, 1 descend
            'size': -1,
            'updatedAt': -1,
          };
          bodyContent.activeLists = activeLists;
          bodyContent.allLists = allLists;

          this.setState({
            bodyContent: bodyContent
          });
        }
      }).catch((e) => {
        console.log(e);
      })
  }

  initState() {
    const bodyContent = this.state.bodyContent;
    bodyContent.allLists = [];
    bodyContent.activeLists = [];
    bodyContent.listCheckedIds = [];
    bodyContent.bodyTitleIds = [];
    let rootDir;
    try {
      rootDir = JSON.parse(localStorage.rootDir);
    } catch(e) {
      console.log('rootDir json ex: ', e);
    }

    if (rootDir) {
      bodyContent.currentDir = rootDir.title || '';
      bodyContent.currentDirId = rootDir._id || '';
      bodyContent.bodyTitleIds.push(rootDir._id);
    }

    bodyContent.currentDir = this.getMenuAsideButtonName();

    this.setState({
      header: {
        linkActiveIndex: 0,
        userMenuActiveIndex: -1,
      },
      bodyToolBar: {
        buttonActiveIndex: -1,
        searchInfo: '',
      },
      bodyContent: bodyContent,
    }, this.getItemList);
  }

  handleLoginStateChange(isLogin) {
    console.log(isLogin);
    this.setState({
      isLogin: isLogin
    }, this.initState);
  }

  handleHeaderLinkClick(event) {
    const titleClick = event.target.title;
    const header = this.state.header;
    if (titleClick === 'onlineDisk') {
      header.linkActiveIndex = 0;
    } else if (titleClick === 'share') {
      header.linkActiveIndex = 1;
    } else if (titleClick === 'more') {
      header.linkActiveIndex = 2;
    }

    header.userMenuActiveIndex = -1;

    this.setState({
      header: header
    });
  }

  handleUserMenuButtonClick(event) {
    const name = event.target.name;
    const header = this.state.header;
    if (name === 'userInfo') {
      header.userMenuActiveIndex = 0;
    } else if (name === 'help') {
      header.userMenuActiveIndex = 1;
    }

    this.setState({
      header: header
    });
  }

  handleMenuAsideButtonClick(event) {
    const name = event.target.name;
    const menuAside = this.state.menuAside;
    menuAside.buttonActiveIndex = this.getMenuAsideButtonIndexByName(name);
    this.setState({
      menuAside: menuAside,
    }, this.initState);
  }

  getMenuAsideButtonIndexByName(name) {
    const nameMap = {
      all: 0,
      image: 1,
      doc: 2,
      video: 3,
      music: 4,
      trash: 5,
    }
    return nameMap[name] || -1;
  }

  getMenuAsideButtonName() {
    const nameMap = [
      '全部文件',
      '图片',
      '文档',
      '视频',
      '音乐',
      '回收站',
    ];

    return nameMap[this.state.menuAside.buttonActiveIndex] || '全部文件';
  }

  handleToolBarButtonClick(event) {
    const name = event.target.name;
    const bodyToolBar = this.state.bodyToolBar;
    const bodyContent = this.state.bodyContent;
    let activeLists = bodyContent.activeLists;
    let listCheckedIds = bodyContent.listCheckedIds;
    bodyToolBar.buttonActiveIndex = this.getToolBarButtonIndexByName(name);

    const callback = (newItem) => {
      activeLists.unshift(newItem);
      listCheckedIds.push(newItem.id);
      bodyContent.activeLists = activeLists;

      this.setState({
        bodyContent: bodyContent,
        bodyToolBar: bodyToolBar,
      }, () => {
        document.getElementById('input_text_' + activeLists[0].id).focus();
        document.getElementById('input_text_' + activeLists[0].id).select();
      });
    }

    // 新建文件夹
    if (bodyToolBar.buttonActiveIndex === 1) {
       let newItem = {
        id: uniqid(),
        parentId: bodyContent.currentDirId,
        title: '新建文件夹',
        size: '-',
        updatedAt: Helper.dateFormat(new Date()),
        type: 'directory',
        isEdit: true,
      };

      // console.log(activeLists);
      // update to the database.
      fetch('http://localhost:3001/addItem', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(newItem),
        credentials: 'include'
      })
        .then(function(response) {
          return response.json();
        }).then((json) => {
          console.log(json);
          if (json.success === 1 || json.success === '1') {
            callback(newItem);
          } else {
            // 用户未登录
            if (json.code === '110') {
              Helper.isLogin((state) => this.handleLoginStateChange(state));
            }
          }
        }).catch((ex) => {
          console.log(ex);
          Helper.notifyBox('新建文件夹失败, 请稍后重试.', 'danger');
        });
    }

  }

  handleToolBarSearchInfoChange(event) {
    const value = event.target.value;
    const bodyToolBar = this.state.bodyToolBar;
    bodyToolBar.searchInfo = value;
    this.setState({
      bodyToolBar: bodyToolBar
    });
  }

  getToolBarButtonIndexByName(name) {
    let index = -1;
    switch (name) {
      case 'upload':
        index = 0;
        break;
      case 'newDirectory':
        index = 1;
        break;
      case 'download':
        index = 2;
        break;
      case 'searchButton':
        index = 3;
        break;
      default:

    }
    return index;
  }

  handleListItemsAllCheck(event) {
    const checked = event.target.checked;
    let listCheckedIds = [];
    if (checked === true) {
      const lists = this.state.bodyContent.activeLists;
      for (let item of lists) {
        listCheckedIds.push(item.id);
      }
    }
    const bodyContent = this.state.bodyContent;
    bodyContent.listCheckedIds = listCheckedIds;
    this.setState({
      bodyContent: bodyContent
    });

    console.log(listCheckedIds);
  }

  handleListItemCheck(event) {
    const value = event.target.value;
    const checked = event.target.checked;
    console.log(value);
    console.log(checked);
    let listCheckedIds = this.state.bodyContent.listCheckedIds;
    const filterArray = listCheckedIds.filter((val) => val === value);

    if (filterArray.length > 0 && checked === false) {
      listCheckedIds = listCheckedIds.filter((val) => val !== value);
    }

    if (filterArray.length === 0 && checked === true) {
      listCheckedIds.push(value);
    }

    const bodyContent = this.state.bodyContent;
    bodyContent.listCheckedIds = listCheckedIds;
    this.setState({
      bodyContent: bodyContent
    });
    console.log(listCheckedIds);
  }

  updateListCheckedIds(id) {
    let listCheckedIds = this.state.bodyContent.listCheckedIds;
    const filterArray = listCheckedIds.filter((val) => val === id);
    if (filterArray.length > 0) {
      listCheckedIds = listCheckedIds.filter((val) => val !== id);
    } else {
      listCheckedIds.push(id);
    }

    console.log(listCheckedIds);

    const bodyContent = this.state.bodyContent;
    bodyContent.listCheckedIds = listCheckedIds;
    this.setState({
      bodyContent: bodyContent
    });
  }

  handleCurrentDirChange(currentDir, currentDirId) {
    const bodyContent = this.state.bodyContent;
    const bodyTitleIds = bodyContent.bodyTitleIds;
    const dirs = currentDir.split('/').filter((val) => val !== '');

    if (bodyTitleIds.length > dirs.length) {
      bodyTitleIds.length = dirs.length;
    } else {
      bodyTitleIds.push(currentDirId);
    }

    bodyContent.currentDirId = currentDirId;
    bodyContent.currentDir = currentDir;
    this.setState({
      bodyContent: bodyContent
    }, this.getItemList);
  }

  sortActiveLists(comp, name) {
    const activeLists = this.state.bodyContent.activeLists;
    activeLists.sort(comp);
    const bodyContent = this.state.bodyContent;
    bodyContent.activeLists = activeLists;
    bodyContent.sortStatus[name] = bodyContent.sortStatus[name] === 0 ? 1 : 0;
    this.setState({
      bodyContent: bodyContent
    });
  }

  clearSearchInfo() {
    const bodyToolBar = this.state.bodyToolBar;
    bodyToolBar.searchInfo = '';
    this.setState({
      bodyToolBar: bodyToolBar
    });
  }

  updateListItemContent(listItemContent) {
    const activeLists = this.state.bodyContent.activeLists;
    activeLists.forEach((obj) => {
      if (obj.id === listItemContent.id) {
        for (let props in obj) {
          obj[props] = listItemContent[props];
        }
      }
    });

    const bodyContent = this.state.bodyContent;
    bodyContent.activeLists = activeLists;
    this.setState({
      bodyContent: bodyContent,
    }, () => {
      const inputText = document.getElementById('input_text_' + listItemContent.id);
      if (inputText) {
        inputText.focus();
        inputText.select();
      }
    });
  }

  updateActiveLists(activeLists) {
    const bodyContent = this.state.bodyContent;
    let listCheckedIds = bodyContent.listCheckedIds;

    listCheckedIds = listCheckedIds.filter((id) => {
      for (let obj of activeLists) {
        if (id === obj.id) {
          return true;
        }
        return false;
      }
    });

    bodyContent.activeLists = activeLists;
    bodyContent.listCheckedIds = listCheckedIds;

    this.setState({
      bodyContent: bodyContent
    });

    // Todo, update to the database
    Helper.notifyBox('更新成功', 'success');
  }

  render() {
    let appHeader = null;
    let appBody = null;

    if (!this.state.isLogin) {
      appHeader =

;
      appBody = <LoginRegisterBlock onLoginStateChange={(isLogin) => this.handleLoginStateChange(isLogin)}/>;
    }

    if (this.state.isLogin) {
      const activeIndex = this.state.header.userMenuActiveIndex;
      if (activeIndex === 0) {
        appBody =

             this.handleHeaderLinkClick(e)}
              onLoginStateChange={(isLogin) => this.handleLoginStateChange(isLogin)}
              onUserMenuButtonClick={(e) => this.handleUserMenuButtonClick(e)}/>
            <UserInfoCard />

      } else if (activeIndex === -1) {
        appBody =

             this.handleHeaderLinkClick(e)}
              onLoginStateChange={(isLogin) => this.handleLoginStateChange(isLogin)}
              onUserMenuButtonClick={(e) => this.handleUserMenuButtonClick(e)}/>
            <MenuAside
              menuAside={this.state.menuAside}
              onMenuAsideButtonClick={(e) => this.handleMenuAsideButtonClick(e)}/>
            <BodyToolBar
              bodyToolBar={this.state.bodyToolBar}
              bodyContent={this.state.bodyContent}
              menuAside={this.state.menuAside}
              onToolBarButtonClick={(e) => this.handleToolBarButtonClick(e)}
              onToolBarSearchInfoChange={(e) => this.handleToolBarSearchInfoChange(e)}
              onClearSearchInfo={() => this.clearSearchInfo()}
              isItemsChecked={this.state.bodyContent.listCheckedIds.length > 0}
              onUpdateListItemContent={(listItemContent) => this.updateListItemContent(listItemContent)}
              onUpdateActiveLists={(activeLists) => this.updateActiveLists(activeLists)}
              onFetchData={() => this.getItemList()}/>
            <BodyContent
              bodyContent={this.state.bodyContent}
              searchInfo={this.state.bodyToolBar.searchInfo}
              listCheckedIds={this.state.bodyContent.listCheckedIds}
              onUpdateListCheckedIds={(id) => this.updateListCheckedIds(id)}
              onCurrentDirChange={(currentDir, currentDirId) => this.handleCurrentDirChange(currentDir, currentDirId)}
              onItemCheck={(e) => this.handleListItemCheck(e)}
              onItemsAllCheck={(e) => this.handleListItemsAllCheck(e)}
              onSortActiveLists={(comp, name) => this.sortActiveLists(comp, name)}
              onUpdateListItemContent={(listItemContent) => this.updateListItemContent(listItemContent)}
              onUpdateActiveLists={(activeLists) => this.updateActiveLists(activeLists)}/>

;
      } else {
        appBody =

             this.handleHeaderLinkClick(e)}
              onLoginStateChange={(isLogin) => this.handleLoginStateChange(isLogin)}
              onUserMenuButtonClick={(e) => this.handleUserMenuButtonClick(e)}/>

;
      }
    }

    return (

        {appHeader}
        {appBody}

    );
  }
}

export default App;
<commit_msg>fix bug.<commit_after>import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import LoginRegisterBlock from './components/LoginRegisterBlock.js';
import Header from './components/Header.js';
import MenuAside from './components/MenuAside.js';
import BodyToolBar from './components/BodyToolBar.js';
import BodyContent from './components/BodyContent.js';
import UserInfoCard from './components/UserInfoCard.js';
import NotifyBox from './components/NotifyBox.js';
import Helper from './helper.js';
import uniqid from 'uniqid';

class App extends Component {
  constructor() {
    super();
    this.state = {
      isLogin: false,
      header: {
        linkActiveIndex: 0,
        userMenuActiveIndex: -1,
      },
      menuAside: {
        buttonActiveIndex: 0,
      },
      bodyToolBar: {
        buttonActiveIndex: -1,
        searchInfo: '',
      },
      bodyContent: {
        allLists: [],
        activeLists: [],
        listCheckedIds: [],
        bodyTitleIds: [],
        currentDir: '全部文件',
        currentDirId: 'root',
        sortStatus: {
          'title': -1, // -1 unsorted, 0 ascend, 1 descend
          'size': -1,
          'updatedAt': -1,
        },
      }
    };
  }

  componentDidMount() {
    Helper.isLogin((state) => this.handleLoginStateChange(state));
  }

  getItemList() {
    const bodyContent = this.state.bodyContent;
    const menuAside = this.state.menuAside;
    let activeLists = [];
    let allLists = [];

    let fetchLink = 'http://localhost:3001/';
    if (menuAside.buttonActiveIndex === 5 && bodyContent.bodyTitleIds.length === 1) {
      fetchLink += 'getTrashItemList';
    } else {
      fetchLink += 'getItemList/' + bodyContent.currentDirId;
    }

    console.log(fetchLink);
    fetch(fetchLink, {
      method: 'GET',
      credentials: 'include',
    }).then((response) => response.json())
      .then((json) => {
        if (json.success === '1' || json.success === 1) {
          const data = json.data;
          // console.log(bodyContent.activeLists);
          data.map((obj) => {
            obj.isEdit = false;
            allLists.push(obj);
            activeLists.push(obj);
          });

          bodyContent.listCheckedIds = [];
          bodyContent.sortStatus = {
            'title': -1, // -1 unsorted, 0 ascend, 1 descend
            'size': -1,
            'updatedAt': -1,
          };
          bodyContent.activeLists = activeLists;
          bodyContent.allLists = allLists;

          this.setState({
            bodyContent: bodyContent
          });
        }
      }).catch((e) => {
        console.log(e);
      })
  }

  initState() {
    const bodyContent = this.state.bodyContent;
    bodyContent.allLists = [];
    bodyContent.activeLists = [];
    bodyContent.listCheckedIds = [];
    bodyContent.bodyTitleIds = [];
    let rootDir;
    try {
      rootDir = JSON.parse(localStorage.rootDir);
    } catch(e) {
      console.log('rootDir json ex: ', e);
    }

    if (rootDir) {
      bodyContent.currentDir = rootDir.title || '';
      bodyContent.currentDirId = rootDir._id || '';
      bodyContent.bodyTitleIds.push(rootDir._id);
    }

    bodyContent.currentDir = this.getMenuAsideButtonName();

    this.setState({
      header: {
        linkActiveIndex: 0,
        userMenuActiveIndex: -1,
      },
      bodyToolBar: {
        buttonActiveIndex: -1,
        searchInfo: '',
      },
      bodyContent: bodyContent,
    }, this.getItemList);
  }

  handleLoginStateChange(isLogin) {
    console.log(isLogin);
    this.setState({
      isLogin: isLogin
    }, this.initState);
  }

  handleHeaderLinkClick(event) {
    const titleClick = event.target.title;
    const header = this.state.header;
    if (titleClick === 'onlineDisk') {
      header.linkActiveIndex = 0;
    } else if (titleClick === 'share') {
      header.linkActiveIndex = 1;
    } else if (titleClick === 'more') {
      header.linkActiveIndex = 2;
    }

    header.userMenuActiveIndex = -1;

    this.setState({
      header: header
    });
  }

  handleUserMenuButtonClick(event) {
    const name = event.target.name;
    const header = this.state.header;
    if (name === 'userInfo') {
      header.userMenuActiveIndex = 0;
    } else if (name === 'help') {
      header.userMenuActiveIndex = 1;
    }

    this.setState({
      header: header
    });
  }

  handleMenuAsideButtonClick(event) {
    const name = event.target.name;
    const menuAside = this.state.menuAside;
    menuAside.buttonActiveIndex = this.getMenuAsideButtonIndexByName(name);
    this.setState({
      menuAside: menuAside,
    }, this.initState);
  }

  getMenuAsideButtonIndexByName(name) {
    const nameMap = {
      all: 0,
      image: 1,
      doc: 2,
      video: 3,
      music: 4,
      trash: 5,
    }
    if (isNaN(nameMap[name])) {
      return -1;
    }

    return nameMap[name];
  }

  getMenuAsideButtonName() {
    const nameMap = [
      '全部文件',
      '图片',
      '文档',
      '视频',
      '音乐',
      '回收站',
    ];

    return nameMap[this.state.menuAside.buttonActiveIndex] || '全部文件';
  }

  handleToolBarButtonClick(event) {
    const name = event.target.name;
    const bodyToolBar = this.state.bodyToolBar;
    const bodyContent = this.state.bodyContent;
    let activeLists = bodyContent.activeLists;
    let listCheckedIds = bodyContent.listCheckedIds;
    bodyToolBar.buttonActiveIndex = this.getToolBarButtonIndexByName(name);

    const callback = (newItem) => {
      activeLists.unshift(newItem);
      listCheckedIds.push(newItem.id);
      bodyContent.activeLists = activeLists;

      this.setState({
        bodyContent: bodyContent,
        bodyToolBar: bodyToolBar,
      }, () => {
        document.getElementById('input_text_' + activeLists[0].id).focus();
        document.getElementById('input_text_' + activeLists[0].id).select();
      });
    }

    // 新建文件夹
    if (bodyToolBar.buttonActiveIndex === 1) {
       let newItem = {
        id: uniqid(),
        parentId: bodyContent.currentDirId,
        title: '新建文件夹',
        size: '-',
        updatedAt: Helper.dateFormat(new Date()),
        type: 'directory',
        isEdit: true,
      };

      // console.log(activeLists);
      // update to the database.
      fetch('http://localhost:3001/addItem', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(newItem),
        credentials: 'include'
      })
        .then(function(response) {
          return response.json();
        }).then((json) => {
          console.log(json);
          if (json.success === 1 || json.success === '1') {
            callback(newItem);
          } else {
            // 用户未登录
            if (json.code === '110') {
              Helper.isLogin((state) => this.handleLoginStateChange(state));
            }
          }
        }).catch((ex) => {
          console.log(ex);
          Helper.notifyBox('新建文件夹失败, 请稍后重试.', 'danger');
        });
    }

  }

  handleToolBarSearchInfoChange(event) {
    const value = event.target.value;
    const bodyToolBar = this.state.bodyToolBar;
    bodyToolBar.searchInfo = value;
    this.setState({
      bodyToolBar: bodyToolBar
    });
  }

  getToolBarButtonIndexByName(name) {
    let index = -1;
    switch (name) {
      case 'upload':
        index = 0;
        break;
      case 'newDirectory':
        index = 1;
        break;
      case 'download':
        index = 2;
        break;
      case 'searchButton':
        index = 3;
        break;
      default:

    }
    return index;
  }

  handleListItemsAllCheck(event) {
    const checked = event.target.checked;
    let listCheckedIds = [];
    if (checked === true) {
      const lists = this.state.bodyContent.activeLists;
      for (let item of lists) {
        listCheckedIds.push(item.id);
      }
    }
    const bodyContent = this.state.bodyContent;
    bodyContent.listCheckedIds = listCheckedIds;
    this.setState({
      bodyContent: bodyContent
    });

    console.log(listCheckedIds);
  }

  handleListItemCheck(event) {
    const value = event.target.value;
    const checked = event.target.checked;
    console.log(value);
    console.log(checked);
    let listCheckedIds = this.state.bodyContent.listCheckedIds;
    const filterArray = listCheckedIds.filter((val) => val === value);

    if (filterArray.length > 0 && checked === false) {
      listCheckedIds = listCheckedIds.filter((val) => val !== value);
    }

    if (filterArray.length === 0 && checked === true) {
      listCheckedIds.push(value);
    }

    const bodyContent = this.state.bodyContent;
    bodyContent.listCheckedIds = listCheckedIds;
    this.setState({
      bodyContent: bodyContent
    });
    console.log(listCheckedIds);
  }

  updateListCheckedIds(id) {
    let listCheckedIds = this.state.bodyContent.listCheckedIds;
    const filterArray = listCheckedIds.filter((val) => val === id);
    if (filterArray.length > 0) {
      listCheckedIds = listCheckedIds.filter((val) => val !== id);
    } else {
      listCheckedIds.push(id);
    }

    console.log(listCheckedIds);

    const bodyContent = this.state.bodyContent;
    bodyContent.listCheckedIds = listCheckedIds;
    this.setState({
      bodyContent: bodyContent
    });
  }

  handleCurrentDirChange(currentDir, currentDirId) {
    const bodyContent = this.state.bodyContent;
    const bodyTitleIds = bodyContent.bodyTitleIds;
    const dirs = currentDir.split('/').filter((val) => val !== '');

    if (bodyTitleIds.length > dirs.length) {
      bodyTitleIds.length = dirs.length;
    } else {
      bodyTitleIds.push(currentDirId);
    }

    bodyContent.currentDirId = currentDirId;
    bodyContent.currentDir = currentDir;
    this.setState({
      bodyContent: bodyContent
    }, this.getItemList);
  }

  sortActiveLists(comp, name) {
    const activeLists = this.state.bodyContent.activeLists;
    activeLists.sort(comp);
    const bodyContent = this.state.bodyContent;
    bodyContent.activeLists = activeLists;
    bodyContent.sortStatus[name] = bodyContent.sortStatus[name] === 0 ? 1 : 0;
    this.setState({
      bodyContent: bodyContent
    });
  }

  clearSearchInfo() {
    const bodyToolBar = this.state.bodyToolBar;
    bodyToolBar.searchInfo = '';
    this.setState({
      bodyToolBar: bodyToolBar
    });
  }

  updateListItemContent(listItemContent) {
    const activeLists = this.state.bodyContent.activeLists;
    activeLists.forEach((obj) => {
      if (obj.id === listItemContent.id) {
        for (let props in obj) {
          obj[props] = listItemContent[props];
        }
      }
    });

    const bodyContent = this.state.bodyContent;
    bodyContent.activeLists = activeLists;
    this.setState({
      bodyContent: bodyContent,
    }, () => {
      const inputText = document.getElementById('input_text_' + listItemContent.id);
      if (inputText) {
        inputText.focus();
        inputText.select();
      }
    });
  }

  updateActiveLists(activeLists) {
    const bodyContent = this.state.bodyContent;
    let listCheckedIds = bodyContent.listCheckedIds;

    listCheckedIds = listCheckedIds.filter((id) => {
      for (let obj of activeLists) {
        if (id === obj.id) {
          return true;
        }
        return false;
      }
    });

    bodyContent.activeLists = activeLists;
    bodyContent.listCheckedIds = listCheckedIds;

    this.setState({
      bodyContent: bodyContent
    });

    // Todo, update to the database
    Helper.notifyBox('更新成功', 'success');
  }

  render() {
    let appHeader = null;
    let appBody = null;

    if (!this.state.isLogin) {
      appHeader =

;
      appBody = <LoginRegisterBlock onLoginStateChange={(isLogin) => this.handleLoginStateChange(isLogin)}/>;
    }

    if (this.state.isLogin) {
      const activeIndex = this.state.header.userMenuActiveIndex;
      if (activeIndex === 0) {
        appBody =

             this.handleHeaderLinkClick(e)}
              onLoginStateChange={(isLogin) => this.handleLoginStateChange(isLogin)}
              onUserMenuButtonClick={(e) => this.handleUserMenuButtonClick(e)}/>
            <UserInfoCard />

      } else if (activeIndex === -1) {
        appBody =

             this.handleHeaderLinkClick(e)}
              onLoginStateChange={(isLogin) => this.handleLoginStateChange(isLogin)}
              onUserMenuButtonClick={(e) => this.handleUserMenuButtonClick(e)}/>
            <MenuAside
              menuAside={this.state.menuAside}
              onMenuAsideButtonClick={(e) => this.handleMenuAsideButtonClick(e)}/>
            <BodyToolBar
              bodyToolBar={this.state.bodyToolBar}
              bodyContent={this.state.bodyContent}
              menuAside={this.state.menuAside}
              onToolBarButtonClick={(e) => this.handleToolBarButtonClick(e)}
              onToolBarSearchInfoChange={(e) => this.handleToolBarSearchInfoChange(e)}
              onClearSearchInfo={() => this.clearSearchInfo()}
              isItemsChecked={this.state.bodyContent.listCheckedIds.length > 0}
              onUpdateListItemContent={(listItemContent) => this.updateListItemContent(listItemContent)}
              onUpdateActiveLists={(activeLists) => this.updateActiveLists(activeLists)}
              onFetchData={() => this.getItemList()}/>
            <BodyContent
              bodyContent={this.state.bodyContent}
              searchInfo={this.state.bodyToolBar.searchInfo}
              listCheckedIds={this.state.bodyContent.listCheckedIds}
              onUpdateListCheckedIds={(id) => this.updateListCheckedIds(id)}
              onCurrentDirChange={(currentDir, currentDirId) => this.handleCurrentDirChange(currentDir, currentDirId)}
              onItemCheck={(e) => this.handleListItemCheck(e)}
              onItemsAllCheck={(e) => this.handleListItemsAllCheck(e)}
              onSortActiveLists={(comp, name) => this.sortActiveLists(comp, name)}
              onUpdateListItemContent={(listItemContent) => this.updateListItemContent(listItemContent)}
              onUpdateActiveLists={(activeLists) => this.updateActiveLists(activeLists)}/>

;
      } else {
        appBody =

             this.handleHeaderLinkClick(e)}
              onLoginStateChange={(isLogin) => this.handleLoginStateChange(isLogin)}
              onUserMenuButtonClick={(e) => this.handleUserMenuButtonClick(e)}/>

;
      }
    }

    return (

        {appHeader}
        {appBody}

    );
  }
}

export default App;
<|endoftext|>


<commit_before>import React, { Component } from 'react'

class App extends Component {
  render() {
    return (

              Drunk Limit

                test1

                test

    )
  }
}

export default App

<commit_msg>update style<commit_after>import React, { Component } from 'react'

class App extends Component {
  render() {
    return (

              Drunk Limit

                test1

                test

          test

    )
  }
}

export default App

<|endoftext|>


<commit_before>const React = require('react');
const PropTypes = React.PropTypes;
const Board = require('./components/board');
const boardData = require('./data/board');
const Draggable = require('react-draggable');
const chess = require('chess.js');
const game = new chess();

const App = React.createClass({
  getInitialState: function() {
    return {
      game,
      pieces: boardData.squares.map((row) => {
          return row.map((square) => {
            const fetchPiece = game.get(square);
            let piece = (fetchPiece && {
              type: fetchPiece.type,
              color: fetchPiece.color
            })
            return piece;
          })
        })
    };
  },
  componentDidMount: function() {
    this.setState({
      pieces: boardData.squares.map((row) => {
          return row.map((square) => {
            const fetchPiece = game.get(square);
            let piece = (fetchPiece && {
              type: fetchPiece.type,
              color: fetchPiece.color
            })
            return piece;
          })
        })
    });
  },
  handleMove() {
    this.state.game.move({
      from: 'g2',
      to: 'g3'
    });
    this.state.game.move({
      from: 'h2',
      to: 'h4'
    });
    this.state.game.move({
      from: 'g4',
      to: 'g5'
    });
    this.setState({
      game,
      pieces: this.state.pieces
    });
  },
  render() {
    return (

        <button onClick={this.handleMove} className="btn btn-primary">
          Test move
        </button>
        <Board>

            {this.state.game.ascii()}

History

            {
              this.state.game
              .history({ verbose: true })
              .map((move) => {
                return (

                    Color: {move.color}

                    To: {move.to}

                    From: {move.from}

                );
              })
            }

          {
            this.state.pieces.map((row, rowIndex) => {
            return row.map((piece, colIndex) => {
              let coords = boardData.coordinates[rowIndex][colIndex]
              return (
                <Draggable
                  start={coords}
                  grid={[60, 60]}>

                    {piece !== null || undefined
                      ?

                          {piece.type}

                      : null
                    }

                </Draggable>
              );
            });
          })
        }
        </Board>

    );
  }
});

module.exports = App;
<commit_msg>move piece setup into componentDidMount<commit_after>const React = require('react');
const PropTypes = React.PropTypes;
const Board = require('./components/board');
const boardData = require('./data/board');
const Draggable = require('react-draggable');
const chess = require('chess.js');
const game = new chess();

game.move({
  from: 'g2',
  to: 'g3'
});

const App = React.createClass({
  getInitialState() {
    return {
      game,
      pieces: []
    };
  },
  updatePieces(){
    this.setState({
      pieces: boardData.squares.map((row) => {
          return row.map((square) => {
            const fetchPiece = this.state.game.get(square);
            let piece = (fetchPiece && {
              type: fetchPiece.type,
              color: fetchPiece.color
            })
            return piece;
          })
        })
    });

  },
  componentDidMount() {
    this.updatePieces();
  },
  handleMove() {
    this.state.game.move({
      from: 'h2',
      to: 'h4'
    });
    this.state.game.move({
      from: 'g4',
      to: 'g5'
    });
    this.setState({
      game,
      pieces: this.state.pieces
    });
  },
  render() {
    return (

        <button onClick={this.handleMove} className="btn btn-primary">
          Test move
        </button>
        <Board>

            {this.state.game.ascii()}

History

            {
              this.state.game
              .history({ verbose: true })
              .map((move) => {
                return (

                    Color: {move.color}

                    To: {move.to}

                    From: {move.from}

                );
              })
            }

          {
            this.state.pieces.map((row, rowIndex) => {
            return row.map((piece, colIndex) => {
              let coords = boardData.coordinates[rowIndex][colIndex]
              return (
                <Draggable
                  start={coords}
                  grid={[60, 60]}>

                    {piece !== null || undefined
                      ?

                          {piece.type}

                      : null
                    }

                </Draggable>
              );
            });
          })
        }
        </Board>

    );
  }
});

module.exports = App;
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import Header from './header';
import Gallery from './gallery';

class Footer extends Component {
  render(){
    return (

    );
  }
}

export class App extends Component {
  render() {
    var headerOptions = {
      title: "MY PORTFOLIO"
    };

    var galleryOptions = {
      img: [
        { url: "/static/dancing_drakes.jpg", desc: "description 1" },
        { url: "/static/floral_tea_cups.gif", desc: "description 2" },
        { url: "/static/hipster_floral_triangles.jpg", desc: "description 3" },
        { url: "/static/pusheen_the_cats.png", desc: "description 4" }
      ]
    };

    return (

        <Gallery {...galleryOptions} />

    );
  }
}<commit_msg>take out Footer component and import js file<commit_after>import React, { Component } from 'react';
import Header from './header';
import Gallery from './gallery';
import Footer from './footer';

export class App extends Component {
  render() {
    var headerOptions = {
      title: "MY PORTFOLIO"
    };

    var galleryOptions = {
      img: [
        { url: "/static/dancing_drakes.jpg", desc: "description 1" },
        { url: "/static/floral_tea_cups.gif", desc: "description 2" },
        { url: "/static/hipster_floral_triangles.jpg", desc: "description 3" },
        { url: "/static/pusheen_the_cats.png", desc: "description 4" }
      ]
    };

    return (

        <Gallery {...galleryOptions} />

    );
  }
}<|endoftext|>


<commit_before>import React, { Component } from "react";
import $ from "jquery";
import "./App.scss";
import Header from "./components/Header";
import Footer from "./components/Footer";
import About from "./components/About";
import Experience from "./components/Experience";
import Projects from "./components/Projects";
import Skills from "./components/Skills";

class App extends Component {
  constructor(props) {
    super();
    this.state = {
      foo: "bar",
      resumeData: {},
      sharedData: {},
    };
  }

  applyPickedLanguage(pickedLanguage, oppositeLangIconId) {
    this.swapCurrentlyActiveLanguage(oppositeLangIconId);
    document.documentElement.lang = pickedLanguage;
    var resumePath =
      document.documentElement.lang === window.$primaryLanguage
        ? "/res_primaryLanguage.json"
        : "/res_secondaryLanguage.json";
    this.loadResumeFromPath(resumePath);
  }

  swapCurrentlyActiveLanguage(oppositeLangIconId) {
    var pickedLangIconId =
      oppositeLangIconId === window.$primaryLanguageIconId
        ? window.$secondaryLanguageIconId
        : window.$primaryLanguageIconId;
    document
      .getElementById(oppositeLangIconId)
      .removeAttribute("filter", "brightness(40%)");
    document
      .getElementById(pickedLangIconId)
      .setAttribute("filter", "brightness(40%)");
  }

  componentDidMount() {
    this.applyPickedLanguage(
      window.$primaryLanguage,
      window.$secondaryLanguageIconId
    );
    this.loadSharedData();
  }

  loadResumeFromPath(path) {
    $.ajax({
      url: path,
      dataType: "json",
      cache: false,
      success: function (data) {
        this.setState({ resumeData: data });
      }.bind(this),
      error: function (xhr, status, err) {
        alert(err);
      },
    });
  }

  loadSharedData() {
    $.ajax({
      url: "/portfolio_shared_data.json",
      dataType: "json",
      cache: false,
      success: function (data) {
        this.setState({ sharedData: data });
      }.bind(this),
      error: function (xhr, status, err) {
        alert(err);
      },
    });
  }

  render() {
    return (

              this.applyPickedLanguage(
                window.$primaryLanguage,
                window.$secondaryLanguageIconId
              )
            }
            style={{ display: "inline" }}
          >

              this.applyPickedLanguage(
                window.$secondaryLanguage,
                window.$primaryLanguageIconId
              )
            }
            style={{ display: "inline" }}
          >

        <About
          data={this.state.resumeData.basic_info}
          sharedData={this.state.sharedData.basic_info}
        />
        <Projects data={this.state.resumeData.projects} />
        <Skills sharedData={this.state.sharedData.skills} />
        <Experience data={this.state.resumeData.experience} />

    );
  }
}

export default App;
<commit_msg>Update App.js<commit_after>import React, { Component } from "react";
import $ from "jquery";
import "./App.scss";
import Header from "./components/Header";
import Footer from "./components/Footer";
import About from "./components/About";
import Experience from "./components/Experience";
import Projects from "./components/Projects";
import Skills from "./components/Skills";

class App extends Component {
  constructor(props) {
    super();
    this.state = {
      foo: "bar",
      resumeData: {},
      sharedData: {},
    };
  }

  applyPickedLanguage(pickedLanguage, oppositeLangIconId) {
    this.swapCurrentlyActiveLanguage(oppositeLangIconId);
    document.documentElement.lang = pickedLanguage;
    var resumePath =
      document.documentElement.lang === window.$primaryLanguage
        ? "/res_primaryLanguage.json"
        : "/res_secondaryLanguage.json";
    this.loadResumeFromPath(resumePath);
  }

  swapCurrentlyActiveLanguage(oppositeLangIconId) {
    var pickedLangIconId =
      oppositeLangIconId === window.$primaryLanguageIconId
        ? window.$secondaryLanguageIconId
        : window.$primaryLanguageIconId;
    document
      .getElementById(oppositeLangIconId)
      .removeAttribute("filter", "brightness(40%)");
    document
      .getElementById(pickedLangIconId)
      .setAttribute("filter", "brightness(40%)");
  }

  componentDidMount() {
    this.loadSharedData();
    this.applyPickedLanguage(
      window.$primaryLanguage,
      window.$secondaryLanguageIconId
    );
  }

  loadResumeFromPath(path) {
    $.ajax({
      url: path,
      dataType: "json",
      cache: false,
      success: function (data) {
        this.setState({ resumeData: data });
      }.bind(this),
      error: function (xhr, status, err) {
        alert(err);
      },
    });
  }

  loadSharedData() {
    $.ajax({
      url: "/portfolio_shared_data.json",
      dataType: "json",
      cache: false,
      success: function (data) {
        this.setState({ sharedData: data });
      }.bind(this),
      error: function (xhr, status, err) {
        alert(err);
      },
    });
  }

  render() {
    return (

              this.applyPickedLanguage(
                window.$primaryLanguage,
                window.$secondaryLanguageIconId
              )
            }
            style={{ display: "inline" }}
          >

              this.applyPickedLanguage(
                window.$secondaryLanguage,
                window.$primaryLanguageIconId
              )
            }
            style={{ display: "inline" }}
          >

        <About
          data={this.state.resumeData.basic_info}
          sharedData={this.state.sharedData.basic_info}
        />
        <Projects data={this.state.resumeData.projects} />
        <Skills sharedData={this.state.sharedData.skills} />
        <Experience data={this.state.resumeData.experience} />

    );
  }
}

export default App;
<|endoftext|>