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

  angular.module('exceptionless.simple-stack-trace', [
    'ngSanitize',

    'exceptionless',
    'exceptionless.simple-error'
  ])
    .directive('simpleStackTrace', function ($ExceptionlessClient, $sanitize, $sce, simpleErrorService) {
      function buildStackFrames(exceptions) {
        var frames = '';
        for (var index = 0; index < exceptions.length; index++) {
          var stackTrace = exceptions[index].stack_trace;
          if (!!stackTrace) {
            frames += '
' + escapeHTML(stackTrace.replace(' ', ''));

            if (index < (exceptions.length - 1)) {
              frames += '
--- End of inner exception stack trace ---
';
            }

            frames += '
';
          }
        }

        return frames;
      }

      function buildStackTrace(exceptions) {
        return buildStackTraceHeader(exceptions) + buildStackFrames(exceptions.reverse());
      }

      function buildStackTraceHeader(exceptions) {
        var header = '';
        for (var index = 0; index < exceptions.length; index++) {
          header += '';

          if (index > 0) {
            header += ' ---> ';
          }

          var hasType = !!exceptions[index].type;
          if (hasType) {
            header += '' + escapeHTML(exceptions[index].type) + ': ';
          }

          if (exceptions[index].message) {
            header += '' + escapeHTML(exceptions[index].message) + '';
          }

          if (hasType) {
            header += '';
          }
        }

        return header;
      }

      function escapeHTML(input) {
        if (!input || !input.replace) {
          return input;
        }

        return $sce.trustAsHtml(input
          .replace(/&/g, "&")
          .replace(/</g, "<")
          .replace(/>/g, ">")
          .replace(/"/g, """)
          .replace(/'/g, "'"));
      }

      return {
        bindToController: true,
        restrict: 'E',
        replace: true,
        scope: {
          exception: "="
        },
        template: '

',
        controller: [function () {
          var vm = this;
          this.$onInit = function $onInit() {
            vm.stackTrace = $sce.trustAsHtml(buildStackTrace(simpleErrorService.getExceptions(vm.exception)));
          }
        }],
        controllerAs: 'vm'
      };
    });
}());
<commit_msg>Fixed listing error<commit_after>(function () {
  'use strict';

  angular.module('exceptionless.simple-stack-trace', [
    'ngSanitize',

    'exceptionless',
    'exceptionless.simple-error'
  ])
    .directive('simpleStackTrace', function ($ExceptionlessClient, $sanitize, $sce, simpleErrorService) {
      function buildStackFrames(exceptions) {
        var frames = '';
        for (var index = 0; index < exceptions.length; index++) {
          var stackTrace = exceptions[index].stack_trace;
          if (!!stackTrace) {
            frames += '
' + escapeHTML(stackTrace.replace(' ', ''));

            if (index < (exceptions.length - 1)) {
              frames += '
--- End of inner exception stack trace ---
';
            }

            frames += '
';
          }
        }

        return frames;
      }

      function buildStackTrace(exceptions) {
        return buildStackTraceHeader(exceptions) + buildStackFrames(exceptions.reverse());
      }

      function buildStackTraceHeader(exceptions) {
        var header = '';
        for (var index = 0; index < exceptions.length; index++) {
          header += '';

          if (index > 0) {
            header += ' ---> ';
          }

          var hasType = !!exceptions[index].type;
          if (hasType) {
            header += '' + escapeHTML(exceptions[index].type) + ': ';
          }

          if (exceptions[index].message) {
            header += '' + escapeHTML(exceptions[index].message) + '';
          }

          if (hasType) {
            header += '';
          }
        }

        return header;
      }

      function escapeHTML(input) {
        if (!input || !input.replace) {
          return input;
        }

        return $sce.trustAsHtml(input
          .replace(/&/g, "&")
          .replace(/</g, "<")
          .replace(/>/g, ">")
          .replace(/"/g, """)
          .replace(/'/g, "'"));
      }

      return {
        bindToController: true,
        restrict: 'E',
        replace: true,
        scope: {
          exception: "="
        },
        template: '

',
        controller: [function () {
          var vm = this;
          this.$onInit = function $onInit() {
            vm.stackTrace = $sce.trustAsHtml(buildStackTrace(simpleErrorService.getExceptions(vm.exception)));
          };
        }],
        controllerAs: 'vm'
      };
    });
}());
<|endoftext|>


<commit_before><commit_msg>added stringbuilder<commit_after>var StringBuilder = function(value) {
  this._strings = [];
  value = value || '';
  this._strings[0] = value;
};

StringBuilder.prototype.append = function(value) {
  this._strings.push(value);
};

StringBuilder.prototype.toString = function() {
  return this._strings.join('');
};
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { Link } from 'react-router'
import '../styles/Match.css';

class Match extends Component {
  constructor(props) {
    super(props)

    this.renderMatchCard = this.renderMatchCard.bind(this)
    this.renderMatchCondensed = this.renderMatchCondensed.bind(this)
  }

  renderMatchCard() {
    const { awayTeam, date, time, ticketPrice } = this.props.matchData

    return (

{awayTeam.name}

            {date.toUpperCase()} - {time}

            ${(ticketPrice / 100).toFixed(2)}

    )
  }

  renderMatchCondensed() {
    const { id, awayTeam, date, time, location } = this.props.matchData

    return (
      <Link to={`/matches/${id}`}>

{awayTeam.name}

{date} - {time}

{location}

      </Link>
    )
  }

  render() {
    return (

        {
          this.props.condensed
          ? this.renderMatchCondensed()
          : this.renderMatchCard()
        }

    )
  }
}

Match.propTypes =  {
  matchData: React.PropTypes.object.isRequired,
};

export default Match
<commit_msg>fix spacing<commit_after>import React, { Component } from 'react';
import { Link } from 'react-router'
import '../styles/Match.css';

class Match extends Component {
  constructor(props) {
    super(props)

    this.renderMatchCard = this.renderMatchCard.bind(this)
    this.renderMatchCondensed = this.renderMatchCondensed.bind(this)
  }

  renderMatchCard() {
    const { awayTeam, date, time, ticketPrice } = this.props.matchData

    return (

{awayTeam.name}

 {date.toUpperCase()} - {time}

 ${(ticketPrice / 100).toFixed(2)}

    )
  }

  renderMatchCondensed() {
    const { id, awayTeam, date, time, location } = this.props.matchData

    return (
      <Link to={`/matches/${id}`}>

{awayTeam.name}

{date} - {time}

{location}

      </Link>
    )
  }

  render() {
    return (

        {
          this.props.condensed
          ? this.renderMatchCondensed()
          : this.renderMatchCard()
        }

    )
  }
}

Match.propTypes =  {
  matchData: React.PropTypes.object.isRequired,
};

export default Match
<|endoftext|>


<commit_before>import React from 'react';

const mediaEvents = [
  'abort', 'canplay', 'canplaythrough', 'durationchange', 'emptied', 'encrypted', 'ended',
  'error', 'interruptbegin', 'interruptend', 'loadeddata', 'loadedmetadata', 'loadstart',
  'onencrypted', 'pause', 'play', 'playing', /* 'progress', */ 'ratechange', 'seeked', 'seeking',
  'stalled', /* 'suspend', */ 'timeupdate', 'volumechange', 'waiting',
];

const noop = () => {};

export default class Video extends React.Component {

  static propTypes = {
    src: React.PropTypes.string.isRequired,
    // eslint-disable-next-line react/no-unused-prop-types
    playing: React.PropTypes.bool.isRequired,
    // eslint-disable-next-line react/no-unused-prop-types
    position: React.PropTypes.number.isRequired,
    // eslint-disable-next-line react/forbid-prop-types
    style: React.PropTypes.object,
    className: React.PropTypes.string,
    onTimeUpdate: React.PropTypes.func.isRequired,
    onLoadedMetadata: React.PropTypes.func.isRequired,
    onClick: React.PropTypes.func,
  }

  static defaultProps = {
    onTimeUpdate: noop,
    onLoadedMetadata: noop,
  }

  componentDidMount() {
    const video = this.videoNode;

    for (const mediaEvent of mediaEvents) {
      video.addEventListener(mediaEvent, ::this.onMediaEvent, true);
    }

    this.updateVideoElement(this.props);
  }

  componentWillReceiveProps(nextProps) {
    this.updateVideoElement(nextProps);
  }

  componentWillUnmount() {
    const video = this.videoNode;

    for (const mediaEvent of mediaEvents) {
      video.removeEventListener(mediaEvent, ::this.onMediaEvent, true);
    }
  }

  onMediaEvent(event) {
    const video = event.target;

    if (event.type === 'timeupdate') {
      this.currentVideoPos = video.currentTime;
      this.props.onTimeUpdate(this.currentVideoPos);
    } else if (event.type === 'loadedmetadata') {
      this.props.onLoadedMetadata({ duration: video.duration });
    }
  }

  currentVideoPos = 0;

  updateVideoElement(props) {
    const video = this.videoNode;
    const { playing, position } = props;

    if (this.currentVideoPos !== position) {
      video.currentTime = position;
    }

    if (playing && video.paused) {
      video.play();
    } else if (!playing && !video.paused) {
      video.pause();
    }
  }

  render() {
    const { onClick, src, style, className } = this.props;

    return (
      // eslint-disable-next-line jsx-a11y/no-static-element-interactions
      <video
        ref={(el) => { this.videoNode = el; }}
        src={src}
        onClick={onClick}
        style={style}
        className={className}
      />
    );
  }
}
<commit_msg>fix video component<commit_after>import React from 'react';

const mediaEvents = [
  'abort', 'canplay', 'canplaythrough', 'durationchange', 'emptied', 'encrypted', 'ended',
  'error', 'interruptbegin', 'interruptend', 'loadeddata', 'loadedmetadata', 'loadstart',
  'onencrypted', 'pause', 'play', 'playing', /* 'progress', */ 'ratechange', 'seeked', 'seeking',
  'stalled', /* 'suspend', */ 'timeupdate', 'volumechange', 'waiting',
];

const noop = () => {};

export default class Video extends React.Component {

  static propTypes = {
    src: React.PropTypes.string.isRequired,
    // eslint-disable-next-line react/no-unused-prop-types
    playing: React.PropTypes.bool.isRequired,
    // eslint-disable-next-line react/no-unused-prop-types
    position: React.PropTypes.number.isRequired,
    // eslint-disable-next-line react/forbid-prop-types
    style: React.PropTypes.object,
    className: React.PropTypes.string,
    onTimeUpdate: React.PropTypes.func.isRequired,
    onLoadedMetadata: React.PropTypes.func.isRequired,
    onClick: React.PropTypes.func,
  }

  static defaultProps = {
    onTimeUpdate: noop,
    onLoadedMetadata: noop,
    position: 0,
  }

  componentDidMount() {
    const video = this.videoNode;

    for (const mediaEvent of mediaEvents) {
      video.addEventListener(mediaEvent, this.onMediaEvent, true);
    }

    this.updateVideoElement(this.props);
  }

  componentWillReceiveProps(nextProps) {
    this.updateVideoElement(nextProps);
  }

  componentWillUnmount() {
    const video = this.videoNode;

    for (const mediaEvent of mediaEvents) {
      video.removeEventListener(mediaEvent, this.onMediaEvent, true);
    }
  }

  onMediaEvent = (event) => {
    const video = event.target;

    if (event.type === 'timeupdate') {
      this.currentVideoPos = video.currentTime;
      this.props.onTimeUpdate(this.currentVideoPos);
    } else if (event.type === 'loadedmetadata') {
      this.props.onLoadedMetadata({ duration: video.duration });
    }
  }

  currentVideoPos = 0;

  updateVideoElement(props) {
    const video = this.videoNode;
    const { playing, position } = props;

    if (this.currentVideoPos !== position) {
      video.currentTime = position;
    }

    if (playing && video.paused) {
      video.play();
    } else if (!playing && !video.paused) {
      video.pause();
    }
  }

  render() {
    const { onClick, src, style, className } = this.props;

    return (
      // eslint-disable-next-line jsx-a11y/no-static-element-interactions
      <video
        ref={(el) => { this.videoNode = el; }}
        src={src}
        onClick={onClick}
        style={style}
        className={className}
      />
    );
  }
}
<|endoftext|>


<commit_before>import * as THREE from 'three';

const OrbitControls = require('three-orbit-controls')(THREE);

export default class Three {
  constructor({
    container = null,
    transparent = false,
    alpha = 1.0,
    color = 0xffffff,
    cameraPositionX = 0,
    cameraPositionY = 0,
    cameraPositionZ = 20,
  }) {
    this.scene = null;
    this.camera = null;
    this.renderer = null;
    this.controls = null;

    this.container = container;
    this.width = this.container.clientWidth;
    this.height = this.container.clientHeight;

    this.transparent = transparent;
    this.alpha = alpha;
    this.color = color;
    this.cameraPositionX = cameraPositionX;
    this.cameraPositionY = cameraPositionY;
    this.cameraPositionZ = cameraPositionZ;
  }
  init() {
    this.scene = new THREE.Scene();
    this.camera = new THREE.PerspectiveCamera(50, this.width / this.height, 0.1, 10000);
    this.camera.position.set(this.cameraPositionX, this.cameraPositionY, this.cameraPositionZ);
    this.camera.lookAt(this.scene.position);

    this.renderer = new THREE.WebGLRenderer({ alpha: this.transparent });
    this.renderer.setPixelRatio(window.devicePixelRatio);
    this.renderer.setSize(this.width, this.height);
    this.renderer.setClearColor(this.color, this.alpha);

    this.container.appendChild(this.renderer.domElement);

    this.controls = new OrbitControls(this.camera, this.renderer.domElement);

    window.addEventListener('resize', this.onResize.bind(this));
  }
  onResize() {
    this.width = this.container.clientWidth;
    this.height = this.container.clientHeight;
    this.camera.aspect = this.width / this.height;
    this.camera.updateProjectionMatrix();
    this.renderer.setSize(this.width, this.height);
  }
  render() {
    this.renderer.render(this.scene, this.camera);
  }
}
<commit_msg>Update shadowMap<commit_after>import * as THREE from 'three';

const OrbitControls = require('three-orbit-controls')(THREE);

export default class Three {
  constructor({
    container = null,
    transparent = false,
    alpha = 1.0,
    color = 0xffffff,
    cameraPositionX = 0,
    cameraPositionY = 0,
    cameraPositionZ = 20,
  }) {
    this.scene = null;
    this.camera = null;
    this.renderer = null;
    this.controls = null;

    this.container = container;
    this.width = this.container.clientWidth;
    this.height = this.container.clientHeight;

    this.transparent = transparent;
    this.alpha = alpha;
    this.color = color;
    this.cameraPositionX = cameraPositionX;
    this.cameraPositionY = cameraPositionY;
    this.cameraPositionZ = cameraPositionZ;
  }
  init() {
    this.scene = new THREE.Scene();
    this.camera = new THREE.PerspectiveCamera(50, this.width / this.height, 0.1, 10000);
    this.camera.position.set(this.cameraPositionX, this.cameraPositionY, this.cameraPositionZ);
    this.camera.lookAt(this.scene.position);

    this.renderer = new THREE.WebGLRenderer({ alpha: this.transparent });
    this.renderer.setPixelRatio(window.devicePixelRatio);
    this.renderer.setSize(this.width, this.height);
    this.renderer.setClearColor(this.color, this.alpha);
    this.renderer.shadowMap.enabled = true;
    this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;

    this.container.appendChild(this.renderer.domElement);

    this.controls = new OrbitControls(this.camera, this.renderer.domElement);

    window.addEventListener('resize', this.onResize.bind(this));
  }
  onResize() {
    this.width = this.container.clientWidth;
    this.height = this.container.clientHeight;
    this.camera.aspect = this.width / this.height;
    this.camera.updateProjectionMatrix();
    this.renderer.setSize(this.width, this.height);
  }
  render() {
    this.renderer.render(this.scene, this.camera);
  }
}
<|endoftext|>


<commit_before>var URL = require('url');

module.exports = {
  /**
   * Skip opening the link through Facebook.
   */
  skipFacebookRedirect: function(url) {
    var parsed = URL.parse(url, true);
    var hostMatches = parsed.hostname.indexOf('facebook.com') > -1 || parsed.hostname.indexOf('messenger.com') > -1;
    var pathMatches = parsed.pathname.indexOf('/l.php') > -1;

    if (hostMatches && pathMatches && parsed.query.u) {
      url = decodeURIComponent(parsed.query.u);
    }

    return url;
  },
  /**
   * Reload when computer wakes up.
   * Tracks time difference, if the difference is greater than 3 minutes. The window reloads.
   * If we know how long Messenger's session takes to timeout, perhaps use that time instead?
   *
   * Notes:
   *   V8 caches date information, the current minute is updated at most, once per minute.
   *   This means if the system time jumps, it might take up to a minute before the time is
   *   represented by new Date().
   *
   *   It is unknown how often the hour is updated, but assumed that it is checked also once
   *   per minute and not cached for longer.
   *
   *   The absolute local time difference is tracked, this will cause MFD to reload when you
   *   cross timezones also. This may or may not be desired, and could be fixed using
   *   getTimezoneOffset(), or using UTC time.
   *
   *   Although it's unlikely that the time will result in a reload more than once a minute
   *   due to time caching, it's possible that the bug/feature might be resolved in the future.
   *   It's because of that motivation that the timeout remains at once per second. If the time
   *   is cached, there is no performance impact, and if in the future it isn't cached. We can
   *   profile and fix it at a later time. Overall a quick refresh means we reload as fast as
   *   V8 will let us.
   */
  watchComputerWake: function(win, winBehaviour, document) {
    var time = new Date().getTime();
    setInterval(function() {
      var currentTime = new Date().getTime();
      var deltaTime = Math.abs(currentTime - time);
      if (deltaTime > 60000 * 3) {  // Time in ms. 3 minutes.
		// Remove the iframe to prevent interaction on an old session.
		iframe = document.querySelector('iframe');
		if(iframe) {
			iframe.remove();
		}
        // Save the window state and reload.
        winBehaviour.saveWindowState(win);
        win.reload();
        /**
         * Rerun the online check.
         * We might have changed locations and no longer have internet access
         */
        this.checkForOnline(win);
      }
	  time = currentTime;
    }.bind(this), 1000);
  },
  /**
   * Reloads the app once every 10 seconds until the browser is in online mode.
   */
  checkForOnline: function(win) {
    var reloadIntervalId = setInterval(function() {
      if (win.window.navigator.onLine) {
        clearInterval(reloadIntervalId);
      } else {
        win.reload();
      }
    }, 10 * 1000);
  },
  /**
   * Climbs the prototype hierachy looking for the top Object and returns it
   */
  getRootObject: function(object) {
	  while(object.__proto__) {
		  object = object.__proto__;
	  }
	  return object;
  },
  /**
   * Checks if two objects exist in the same context.
   * Climbs up to the root Object(){} and checks if the constructors are
   * identical. If they are not, it's a separate global context
   */
  areSameContext: function(object1, object2) {
	  root1 = this.getRootObject(object1);
	  root2 = this.getRootObject(object2);
	  return root1.constructor == root2.constructor;
  },
  /**
   * Checks if the passed in Object exists in the Node.JS context
   */
  isNodeContext: function(testObject) {
	  // Modules are loaded in node.js context
	  var self = require('./utils');
	  return this.areSameContext(testObject, self);
  }
};
<commit_msg>Create online/offline events to manage view when online state changes<commit_after>var URL = require('url');
var dispatcher = require('./dispatcher');

module.exports = {
  /**
   * Skip opening the link through Facebook.
   */
  skipFacebookRedirect: function(url) {
    var parsed = URL.parse(url, true);
    var hostMatches = parsed.hostname.indexOf('facebook.com') > -1 || parsed.hostname.indexOf('messenger.com') > -1;
    var pathMatches = parsed.pathname.indexOf('/l.php') > -1;

    if (hostMatches && pathMatches && parsed.query.u) {
      url = decodeURIComponent(parsed.query.u);
    }

    return url;
  },
  /**
   * Reload when computer wakes up.
   * Tracks time difference, if the difference is greater than 3 minutes. The window reloads.
   * If we know how long Messenger's session takes to timeout, perhaps use that time instead?
   *
   * Notes:
   *   V8 caches date information, the current minute is updated at most, once per minute.
   *   This means if the system time jumps, it might take up to a minute before the time is
   *   represented by new Date().
   *
   *   It is unknown how often the hour is updated, but assumed that it is checked also once
   *   per minute and not cached for longer.
   *
   *   The absolute local time difference is tracked, this will cause MFD to reload when you
   *   cross timezones also. This may or may not be desired, and could be fixed using
   *   getTimezoneOffset(), or using UTC time.
   *
   *   Although it's unlikely that the time will result in a reload more than once a minute
   *   due to time caching, it's possible that the bug/feature might be resolved in the future.
   *   It's because of that motivation that the timeout remains at once per second. If the time
   *   is cached, there is no performance impact, and if in the future it isn't cached. We can
   *   profile and fix it at a later time. Overall a quick refresh means we reload as fast as
   *   V8 will let us.
   */
  watchComputerWake: function(win, winBehaviour, document) {
    var time = new Date().getTime();
    setInterval(function() {
      var currentTime = new Date().getTime();
      var deltaTime = Math.abs(currentTime - time);
      if (deltaTime > 60000 * 3) {  // Time in ms. 3 minutes.
		// Remove the iframe to prevent interaction on an old session.
		dispatcher.trigger('offline');
        // Save the window state and reload.
        winBehaviour.saveWindowState(win);
        win.reload();
        /**
         * Rerun the online check.
         * We might have changed locations and no longer have internet access
         */
        this.checkForOnline(win);
      }
	  time = currentTime;
    }.bind(this), 1000);
  },
  /**
   * Reloads the app once every 10 seconds until the browser is in online mode.
   */
  checkForOnline: function(win) {
	// Check that we are not already running
	if(this.reloadIntervalId) {
		return;
	} else {
      this.reloadIntervalId = setInterval(function() {
        if (win.window.navigator.onLine) {
		  // The browser has navigated, are we at the right place?
		  frame = win.window.document.querySelector('iframe');
		  childWindowLocation = frame.contentWindow.location;
		  targetURL = URL.parse(frame.src);
		  currentURL = URL.parse(childWindowLocation.href);
		  if(targetURL.host != currentURL.host) {
			  return; // The frame isn't on Facebook. Maybe it's navigated away, or it's on an about: no dns, page.
		  }
          clearInterval(this.reloadIntervalId);
	      delete this.reloadIntervalId;
		  dispatcher.trigger('online');
        } else {
		  dispatcher.trigger('offline');
          win.reload();
        }
      }.bind(this), 10 * 1000);
	}
  },
  /**
   * Climbs the prototype hierachy looking for the top Object and returns it
   */
  getRootObject: function(object) {
	  while(object.__proto__) {
		  object = object.__proto__;
	  }
	  return object;
  },
  /**
   * Checks if two objects exist in the same context.
   * Climbs up to the root Object(){} and checks if the constructors are
   * identical. If they are not, it's a separate global context
   */
  areSameContext: function(object1, object2) {
	  root1 = this.getRootObject(object1);
	  root2 = this.getRootObject(object2);
	  return root1.constructor == root2.constructor;
  },
  /**
   * Checks if the passed in Object exists in the Node.JS context
   */
  isNodeContext: function(testObject) {
	  // Modules are loaded in node.js context
	  var self = require('./utils');
	  return this.areSameContext(testObject, self);
  }
};
<|endoftext|>


<commit_before>import compose from 'recompose/compose'

import enterScope from './enterScope'
import leaveScope from './leaveScope'

// 放在 props 會放漏掉
// 用 Symbol 中間太容易漏傳
// const scopeSym = Symbol()
// const scopeSym = 'scopeSym'

// TODO 一層一層 push 到 context.composeWithScopeStack 裡
// TODO custmize storeKey?
// TODO 分開處理 static expose and dynamic expose?

function composeWithScope (...hocs) {
  return compose(
    enterScope,
    ...hocs,
    leaveScope,
  )
}

export default composeWithScope

<commit_msg>remove comment<commit_after>import compose from 'recompose/compose'

import enterScope from './enterScope'
import leaveScope from './leaveScope'

function composeWithScope (...hocs) {
  return compose(
    enterScope,
    ...hocs,
    leaveScope,
  )
}

export default composeWithScope

<|endoftext|>


<commit_before>var React = require('react');
var L10nSpan = require('../l10n-span');

var NoTrack = React.createClass({
  render: function() {
    /* jshint ignore:start */
    return (

        <L10nSpan l10nId="component_no_track"/>

    );
    /* jshint ignore:end */
  }
});

module.exports = NoTrack;
<commit_msg>rewrite src/views/components/shared/track/no-track.js with ES6 syntax<commit_after>import React from 'react';
import L10nSpan from '../l10n-span';

class NoTrack extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    /* jshint ignore:start */
    return (

        <L10nSpan l10nId="component_no_track"/>

    );
    /* jshint ignore:end */
  }
}

export default NoTrack;
<|endoftext|>


<commit_before>var _ = require('underscore');
var WidgetModel = require('../widget-model');
var LockedCategoriesCollection = require('./locked-categories-collection');

/**
 * Model for a category widget
 */
module.exports = WidgetModel.extend({

  defaults: _.extend(
    {
      type: 'category',
      search: false,
      locked: false
    },
    WidgetModel.prototype.defaults
  ),

  defaultState: _.extend(
    {
      acceptedCategories: [],
      locked: false,
      autoStyle: false
    },
    WidgetModel.prototype.defaultState
  ),

  initialize: function () {
    WidgetModel.prototype.initialize.apply(this, arguments);
    this.lockedCategories = new LockedCategoriesCollection();

    this.listenTo(this.dataviewModel, 'change:allCategoryNames', this._onDataviewAllCategoryNamesChange);
    this.on('change:locked', this._onLockedChange, this);
    this.on('change:collapsed', this._onCollapsedChange, this);
    this.on('change:style.custom_style', this._updateColors, this);
    this.dataviewModel.filter.on('change', function () {
      this.set('acceptedCategories', this._acceptedCategories().pluck('name'));
    }, this);
    this.dataviewModel.once('change:allCategoryNames', function () {
      if (this.get('autoStyle')) {
        this.autoStyle();
      }
    }, this);
  },

  setupSearch: function () {
    this.dataviewModel.setupSearch();
    this.lockedCategories.addItems(this._acceptedCategories().toJSON());
    this.toggleSearch();
  },

  toggleSearch: function () {
    this.set('search', !this.get('search'));
  },

  enableSearch: function () {
    this.set('search', true);
  },

  disableSearch: function () {
    this.set('search', false);
  },

  isSearchEnabled: function () {
    return this.get('search');
  },

  cleanSearch: function () {
    this.dataviewModel.cleanSearch();
    this.lockedCategories.reset([]);
  },

  autoStyle: function () {
    // NOTE: maybe not pre-assing colors to categories?
    this.autoStyler.colors.updateData(this.dataviewModel.get('allCategoryNames'));
    WidgetModel.prototype.autoStyle.call(this);
  },

  _updateColors: function (e) {
    this.autoStyler.colors.updateColors(e.changed.style);
  },

  cancelAutoStyle: function () {
    this.dataviewModel.layer.restoreCartoCSS();
    this.set('autoStyle', false);
  },

  isLocked: function () {
    return this.get('locked');
  },

  canBeLocked: function () {
    return this.isLocked() || this._acceptedCategories().size() > 0;
  },

  canApplyLocked: function () {
    if (this._acceptedCategories().size() !== this.lockedCategories.size()) {
      return true;
    }

    return this._acceptedCategories().any(function (m) {
      return !this.lockedCategories.isItemLocked(m.get('name'));
    }, this);
  },

  applyLocked: function () {
    var currentLocked = this.lockedCategories.getItemsName();
    if (!currentLocked.length) {
      this.unlockCategories();
      return false;
    }

    this.set('locked', true);

    var f = this.dataviewModel.filter;
    f.cleanFilter(false);
    f.accept(currentLocked);
    f.applyFilter();

    this.cleanSearch();
  },

  lockCategories: function () {
    this.set('locked', true);
    this.dataviewModel.fetch();
  },

  unlockCategories: function () {
    this.set('locked', false);
    this.dataviewModel.filter.acceptAll();
  },

  _onDataviewAllCategoryNamesChange: function (m, names) {
    if (this.isAutoStyleEnabled()) {
      if (!this.isAutoStyle()) {
        this.autoStyler.colors.updateData(names);
      }
    }
  },

  _onLockedChange: function (m, isLocked) {
    if (isLocked) {
      this.dataviewModel.enableFilter();
    } else {
      this.dataviewModel.disableFilter();
    }
  },

  _acceptedCategories: function () {
    return this.dataviewModel.filter.acceptedCategories;
  },

  _onCollapsedChange: function (m, isCollapsed) {
    this.dataviewModel.set('enabled', !isCollapsed);
  }

});
<commit_msg>Dont reset styles if not required #470<commit_after>var _ = require('underscore');
var WidgetModel = require('../widget-model');
var LockedCategoriesCollection = require('./locked-categories-collection');

/**
 * Model for a category widget
 */
module.exports = WidgetModel.extend({

  defaults: _.extend(
    {
      type: 'category',
      search: false,
      locked: false
    },
    WidgetModel.prototype.defaults
  ),

  defaultState: _.extend(
    {
      acceptedCategories: [],
      locked: false,
      autoStyle: false
    },
    WidgetModel.prototype.defaultState
  ),

  initialize: function () {
    WidgetModel.prototype.initialize.apply(this, arguments);
    this.lockedCategories = new LockedCategoriesCollection();

    this.listenTo(this.dataviewModel, 'change:allCategoryNames', this._onDataviewAllCategoryNamesChange);
    this.on('change:locked', this._onLockedChange, this);
    this.on('change:collapsed', this._onCollapsedChange, this);
    this.on('change:style.custom_style', this._updateColors, this);
    this.dataviewModel.filter.on('change', function () {
      this.set('acceptedCategories', this._acceptedCategories().pluck('name'));
    }, this);
    this.dataviewModel.once('change:allCategoryNames', function () {
      if (this.get('autoStyle')) {
        this.autoStyle();
      }
    }, this);
  },

  setupSearch: function () {
    this.dataviewModel.setupSearch();
    this.lockedCategories.addItems(this._acceptedCategories().toJSON());
    this.toggleSearch();
  },

  toggleSearch: function () {
    this.set('search', !this.get('search'));
  },

  enableSearch: function () {
    this.set('search', true);
  },

  disableSearch: function () {
    this.set('search', false);
  },

  isSearchEnabled: function () {
    return this.get('search');
  },

  cleanSearch: function () {
    this.dataviewModel.cleanSearch();
    this.lockedCategories.reset([]);
  },

  autoStyle: function () {
    // NOTE: maybe not pre-assing colors to categories?
    this.autoStyler.colors.updateData(this.dataviewModel.get('allCategoryNames'));
    WidgetModel.prototype.autoStyle.call(this);
  },

  _updateColors: function (e) {
    this.autoStyler.colors.updateColors(e.changed.style);
  },

  cancelAutoStyle: function (noRestore) {
    if (!noRestore) {
      this.dataviewModel.layer.restoreCartoCSS();
    }
    this.set('autoStyle', false);
  },

  isLocked: function () {
    return this.get('locked');
  },

  canBeLocked: function () {
    return this.isLocked() || this._acceptedCategories().size() > 0;
  },

  canApplyLocked: function () {
    if (this._acceptedCategories().size() !== this.lockedCategories.size()) {
      return true;
    }

    return this._acceptedCategories().any(function (m) {
      return !this.lockedCategories.isItemLocked(m.get('name'));
    }, this);
  },

  applyLocked: function () {
    var currentLocked = this.lockedCategories.getItemsName();
    if (!currentLocked.length) {
      this.unlockCategories();
      return false;
    }

    this.set('locked', true);

    var f = this.dataviewModel.filter;
    f.cleanFilter(false);
    f.accept(currentLocked);
    f.applyFilter();

    this.cleanSearch();
  },

  lockCategories: function () {
    this.set('locked', true);
    this.dataviewModel.fetch();
  },

  unlockCategories: function () {
    this.set('locked', false);
    this.dataviewModel.filter.acceptAll();
  },

  _onDataviewAllCategoryNamesChange: function (m, names) {
    if (this.isAutoStyleEnabled()) {
      if (!this.isAutoStyle()) {
        this.autoStyler.colors.updateData(names);
      }
    }
  },

  _onLockedChange: function (m, isLocked) {
    if (isLocked) {
      this.dataviewModel.enableFilter();
    } else {
      this.dataviewModel.disableFilter();
    }
  },

  _acceptedCategories: function () {
    return this.dataviewModel.filter.acceptedCategories;
  },

  _onCollapsedChange: function (m, isCollapsed) {
    this.dataviewModel.set('enabled', !isCollapsed);
  }

});
<|endoftext|>


<commit_before>/**
* Project
* @namespace crowdsource.project.services
* @author dmorina neilthemathguy
*/
(function () {
  'use strict';

  angular
    .module('crowdsource.project.services')
    .factory('Project', Project);

  Project.$inject = ['$cookies', '$http', '$q', '$location', 'HttpService'];

  /**
  * @namespace Project
  * @returns {Factory}
  */

  function Project($cookies, $http, $q, $location, HttpService) {
    /**
    * @name Project
    * @desc The Factory to be returned
    */
    var instance = {
      totalTasks: 1
    };
    var Project = {
      syncLocally: syncLocally,
      retrieve: retrieve,
      addProject: addProject,
      getCategories: getCategories,
      getReferenceData: getReferenceData,
      getProjects: getProjects,
      clean: clean,
      addDriveFolder: addDriveFolder,
      getFiles: getFiles
    };

    return Project;

    /**
    * @name addProject
    * @desc Try to create a new project
    * @returns {Promise}
    * @memberOf crowdsource.project.services.Project
    */
    function addProject(project, modules) {
      var settings = {
        url: '/api/project/',
        method: 'POST',
        data: {
          name: project.name,
          description: project.description,
          categories: project.categories,
          modules: modules
        }
      };
      console.log(settings);
      return HttpService.doRequest(settings);
    }

    function getProjects() {
      var settings = {
        url: '/api/project/',
        method: 'GET'
      };
      return HttpService.doRequest(settings);
    }

    function getCategories() {
      var settings = {
        url: '/api/category/',
        method: 'GET'
      };
      return HttpService.doRequest(settings);
    }

    function getReferenceData() {
      return $http({
        url: 'https://api.myjson.com/bins/4ovc8',
        method: 'GET'
      });
    }

    function syncLocally(projectInstance) {
      instance = projectInstance;
    }

    function retrieve() {
      return instance;
    }

    function clean() {
      instance = {};
    }

    function addDriveFolder(name, parent) {
      var settings = {
        url: '/api/google-drive/add-folder/',
        data: {
          name: name,
          parent: parent
        },
        method: 'POST'
      };
      return HttpService.doRequest(settings);
    }

    function getFiles(parent) {
      var settings = {
        url: '/api/google-drive/get-files/',
        data: {
          parent: parent
        },
        method: 'POST'
      };
      return HttpService.doRequest(settings);
    }

  }
})();
<commit_msg>removed prints<commit_after>/**
* Project
* @namespace crowdsource.project.services
* @author dmorina neilthemathguy
*/
(function () {
  'use strict';

  angular
    .module('crowdsource.project.services')
    .factory('Project', Project);

  Project.$inject = ['$cookies', '$http', '$q', '$location', 'HttpService'];

  /**
  * @namespace Project
  * @returns {Factory}
  */

  function Project($cookies, $http, $q, $location, HttpService) {
    /**
    * @name Project
    * @desc The Factory to be returned
    */
    var instance = {
      totalTasks: 1
    };
    var Project = {
      syncLocally: syncLocally,
      retrieve: retrieve,
      addProject: addProject,
      getCategories: getCategories,
      getReferenceData: getReferenceData,
      getProjects: getProjects,
      clean: clean,
      addDriveFolder: addDriveFolder,
      getFiles: getFiles
    };

    return Project;

    /**
    * @name addProject
    * @desc Try to create a new project
    * @returns {Promise}
    * @memberOf crowdsource.project.services.Project
    */
    function addProject(project, modules) {
      var settings = {
        url: '/api/project/',
        method: 'POST',
        data: {
          name: project.name,
          description: project.description,
          categories: project.categories,
          modules: modules
        }
      };
      return HttpService.doRequest(settings);
    }

    function getProjects() {
      var settings = {
        url: '/api/project/',
        method: 'GET'
      };
      return HttpService.doRequest(settings);
    }

    function getCategories() {
      var settings = {
        url: '/api/category/',
        method: 'GET'
      };
      return HttpService.doRequest(settings);
    }

    function getReferenceData() {
      return $http({
        url: 'https://api.myjson.com/bins/4ovc8',
        method: 'GET'
      });
    }

    function syncLocally(projectInstance) {
      instance = projectInstance;
    }

    function retrieve() {
      return instance;
    }

    function clean() {
      instance = {};
    }

    function addDriveFolder(name, parent) {
      var settings = {
        url: '/api/google-drive/add-folder/',
        data: {
          name: name,
          parent: parent
        },
        method: 'POST'
      };
      return HttpService.doRequest(settings);
    }

    function getFiles(parent) {
      var settings = {
        url: '/api/google-drive/get-files/',
        data: {
          parent: parent
        },
        method: 'POST'
      };
      return HttpService.doRequest(settings);
    }

  }
})();
<|endoftext|>


<commit_before>/*
 * Copyright 2018 Crown Copyright
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import React from 'react';
import PropTypes, { object } from 'prop-types';

import { connect } from 'react-redux';
import { compose, lifecycle, withProps } from 'recompose';
import { withRouter } from 'react-router-dom';
import { Button, Icon } from 'semantic-ui-react';
import Mousetrap from 'mousetrap';

import { actionCreators as appChromeActionCreators } from './redux';
import { withExplorerTree } from 'components/DocExplorer';
import withLocalStorage from 'lib/withLocalStorage';
import { openDocRef } from 'prototypes/RecentItems';

import logoInWhite from './logo_white.png';

const { menuItemOpened } = appChromeActionCreators;

const withIsExpanded = withLocalStorage('isExpanded', 'setIsExpanded', true);

const SIDE_BAR_COLOUR = 'blue';

const pathPrefix = '/s';

const getDocumentTreeMenuItems = (openDocRef, treeNode, skipInContractedMenu = false) => ({
  key: treeNode.uuid,
  title: treeNode.name,
  onClick: () => openDocRef(treeNode),
  icon: 'folder',
  style: skipInContractedMenu ? 'doc' : 'nav',
  skipInContractedMenu,
  children:
    treeNode.children &&
    treeNode.children.length > 0 &&
    treeNode.children
      .filter(t => t.type === 'Folder')
      .map(t => getDocumentTreeMenuItems(openDocRef, t, true)),
});

const enhance = compose(
  withExplorerTree,
  connect(
    (
      {
        docExplorer: {
          explorerTree: { documentTree },
        },
        appChrome: { menuItemsOpen },
      },
      props,
    ) => ({
      documentTree,
      menuItemsOpen,
    }),
    {
      menuItemOpened,
      openDocRef,
    },
  ),
  withRouter,
  withIsExpanded,
  lifecycle({
    componentDidMount() {
      Mousetrap.bind('ctrl+shift+e', () => this.props.history.push('/s/recentItems'));
      Mousetrap.bind('ctrl+shift+f', () => this.props.history.push('/s/search'));
    },
  }),
  withProps(({
    history, openDocRef, actionBarItems, documentTree,
  }) => ({
    menuItems: [
      {
        key: 'welcome',
        title: 'Welcome',
        onClick: () => history.push(`${pathPrefix}/welcome/`),
        icon: 'home',
        style: 'nav',
      },
      getDocumentTreeMenuItems(d => openDocRef(history, d), documentTree),
      {
        key: 'data',
        title: 'Data',
        onClick: () => history.push(`${pathPrefix}/data`),
        icon: 'database',
        style: 'nav',
      },
      {
        key: 'pipelines',
        title: 'Pipelines',
        onClick: () => history.push(`${pathPrefix}/pipelines`),
        icon: 'tasks',
        style: 'nav',
      },
      {
        key: 'processing',
        title: 'Processing',
        onClick: () => history.push(`${pathPrefix}/processing`),
        icon: 'play',
        style: 'nav',
      },
      {
        key: 'admin',
        title: 'Admin',
        onClick: () => {},
        icon: 'cogs',
        style: 'nav',
        skipInContractedMenu: true,
        children: [
          {
            key: 'admin-me',
            title: 'Me',
            onClick: () => history.push(`${pathPrefix}/me`),
            icon: 'user',
            style: 'nav',
          },
          {
            key: 'admin-users',
            title: 'Users',
            onClick: () => history.push(`${pathPrefix}/users`),
            icon: 'users',
            style: 'nav',
          },
          {
            key: 'admin-apikeys',
            title: 'API Keys',
            onClick: () => history.push(`${pathPrefix}/apikeys`),
            icon: 'key',
            style: 'nav',
          },
        ],
      },
      {
        key: 'recent-items',
        title: 'Recent Items',
        onClick: () => history.push(`${pathPrefix}/recentItems`),
        icon: 'file outline',
        style: 'nav',
      },
      {
        key: 'search',
        title: 'Search',
        onClick: () => history.push(`${pathPrefix}/search`),
        icon: 'search',
        style: 'nav',
      },
    ],
  })),
);

const getExpandedMenuItems = (menuItems, menuItemsOpen, menuItemOpened, depth = 0) =>
  menuItems.map(menuItem => (
    <React.Fragment key={menuItem.key}>
      <div
        className={`sidebar__menu-item--${menuItem.style}`}
        style={{ paddingLeft: `${depth * 0.7}rem` }}
      >
        {menuItem.children && menuItem.children.length > 0 ? (
          <Icon
            onClick={(e) => {
              menuItemOpened(menuItem.key, !menuItemsOpen[menuItem.key]);
              e.preventDefault();
            }}
            name={`caret ${menuItemsOpen[menuItem.key] ? 'down' : 'right'}`}
          />
        ) : menuItem.key !== 'stroom' ? (
          <Icon />
        ) : (
          undefined
        )}
        <Icon name={menuItem.icon} />
         {
            if (menuItem.children) {
              menuItemOpened(menuItem.key, !menuItemsOpen[menuItem.key]);
            }
            menuItem.onClick();
          }}
        >
          {menuItem.title}

      {menuItem.children &&
        menuItemsOpen[menuItem.key] &&
        getExpandedMenuItems(menuItem.children, menuItemsOpen, menuItemOpened, depth + 1)}
    </React.Fragment>
  ));

const getContractedMenuItems = menuItems =>
  menuItems.map(menuItem => (
    <React.Fragment key={menuItem.key}>
      {!menuItem.skipInContractedMenu && ( // just put the children of menu items into the sidebar
        <Button key={menuItem.title} icon={menuItem.icon} onClick={menuItem.onClick} />
      )}
      {menuItem.children && getContractedMenuItems(menuItem.children)}
    </React.Fragment>
  ));

const AppChrome = ({
  headerContent,
  icon,
  content,
  isExpanded,
  menuItems,
  actionBarItems,
  menuItemsOpen,
  menuItemOpened,
  setIsExpanded,
}) => (

      {isExpanded ? (
        <React.Fragment>

            <Button
              size="large"
              color={SIDE_BAR_COLOUR}
              icon="bars"
              onClick={() => setIsExpanded(!isExpanded)}
            />

            {getExpandedMenuItems(menuItems, menuItemsOpen, menuItemOpened)}

        </React.Fragment>
      ) : (
        <Button.Group vertical color={SIDE_BAR_COLOUR}>
          <Button size="large" icon="bars" onClick={() => setIsExpanded(!isExpanded)} />
          {getContractedMenuItems(menuItems)}
        </Button.Group>
      )}

{content}

);

AppChrome.contextTypes = {
  store: PropTypes.object,
  router: PropTypes.shape({
    history: object.isRequired,
  }),
};

AppChrome.propTypes = {
  activeMenuItem: PropTypes.string.isRequired,
  content: PropTypes.object.isRequired,
};

export default enhance(AppChrome);
<commit_msg>Add label to fix accessibility issue<commit_after>/*
 * Copyright 2018 Crown Copyright
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import React from 'react';
import PropTypes, { object } from 'prop-types';

import { connect } from 'react-redux';
import { compose, lifecycle, withProps } from 'recompose';
import { withRouter } from 'react-router-dom';
import { Button, Icon } from 'semantic-ui-react';
import Mousetrap from 'mousetrap';

import { actionCreators as appChromeActionCreators } from './redux';
import { withExplorerTree } from 'components/DocExplorer';
import withLocalStorage from 'lib/withLocalStorage';
import { openDocRef } from 'prototypes/RecentItems';

import logoInWhite from './logo_white.png';

const { menuItemOpened } = appChromeActionCreators;

const withIsExpanded = withLocalStorage('isExpanded', 'setIsExpanded', true);

const SIDE_BAR_COLOUR = 'blue';

const pathPrefix = '/s';

const getDocumentTreeMenuItems = (openDocRef, treeNode, skipInContractedMenu = false) => ({
  key: treeNode.uuid,
  title: treeNode.name,
  onClick: () => openDocRef(treeNode),
  icon: 'folder',
  style: skipInContractedMenu ? 'doc' : 'nav',
  skipInContractedMenu,
  children:
    treeNode.children &&
    treeNode.children.length > 0 &&
    treeNode.children
      .filter(t => t.type === 'Folder')
      .map(t => getDocumentTreeMenuItems(openDocRef, t, true)),
});

const enhance = compose(
  withExplorerTree,
  connect(
    (
      {
        docExplorer: {
          explorerTree: { documentTree },
        },
        appChrome: { menuItemsOpen },
      },
      props,
    ) => ({
      documentTree,
      menuItemsOpen,
    }),
    {
      menuItemOpened,
      openDocRef,
    },
  ),
  withRouter,
  withIsExpanded,
  lifecycle({
    componentDidMount() {
      Mousetrap.bind('ctrl+shift+e', () => this.props.history.push('/s/recentItems'));
      Mousetrap.bind('ctrl+shift+f', () => this.props.history.push('/s/search'));
    },
  }),
  withProps(({
    history, openDocRef, actionBarItems, documentTree,
  }) => ({
    menuItems: [
      {
        key: 'welcome',
        title: 'Welcome',
        onClick: () => history.push(`${pathPrefix}/welcome/`),
        icon: 'home',
        style: 'nav',
      },
      getDocumentTreeMenuItems(d => openDocRef(history, d), documentTree),
      {
        key: 'data',
        title: 'Data',
        onClick: () => history.push(`${pathPrefix}/data`),
        icon: 'database',
        style: 'nav',
      },
      {
        key: 'pipelines',
        title: 'Pipelines',
        onClick: () => history.push(`${pathPrefix}/pipelines`),
        icon: 'tasks',
        style: 'nav',
      },
      {
        key: 'processing',
        title: 'Processing',
        onClick: () => history.push(`${pathPrefix}/processing`),
        icon: 'play',
        style: 'nav',
      },
      {
        key: 'admin',
        title: 'Admin',
        onClick: () => {},
        icon: 'cogs',
        style: 'nav',
        skipInContractedMenu: true,
        children: [
          {
            key: 'admin-me',
            title: 'Me',
            onClick: () => history.push(`${pathPrefix}/me`),
            icon: 'user',
            style: 'nav',
          },
          {
            key: 'admin-users',
            title: 'Users',
            onClick: () => history.push(`${pathPrefix}/users`),
            icon: 'users',
            style: 'nav',
          },
          {
            key: 'admin-apikeys',
            title: 'API Keys',
            onClick: () => history.push(`${pathPrefix}/apikeys`),
            icon: 'key',
            style: 'nav',
          },
        ],
      },
      {
        key: 'recent-items',
        title: 'Recent Items',
        onClick: () => history.push(`${pathPrefix}/recentItems`),
        icon: 'file outline',
        style: 'nav',
      },
      {
        key: 'search',
        title: 'Search',
        onClick: () => history.push(`${pathPrefix}/search`),
        icon: 'search',
        style: 'nav',
      },
    ],
  })),
);

const getExpandedMenuItems = (menuItems, menuItemsOpen, menuItemOpened, depth = 0) =>
  menuItems.map(menuItem => (
    <React.Fragment key={menuItem.key}>
      <div
        className={`sidebar__menu-item--${menuItem.style}`}
        style={{ paddingLeft: `${depth * 0.7}rem` }}
      >
        {menuItem.children && menuItem.children.length > 0 ? (
          <Icon
            onClick={(e) => {
              menuItemOpened(menuItem.key, !menuItemsOpen[menuItem.key]);
              e.preventDefault();
            }}
            name={`caret ${menuItemsOpen[menuItem.key] ? 'down' : 'right'}`}
          />
        ) : menuItem.key !== 'stroom' ? (
          <Icon />
        ) : (
          undefined
        )}
        <Icon name={menuItem.icon} />
         {
            if (menuItem.children) {
              menuItemOpened(menuItem.key, !menuItemsOpen[menuItem.key]);
            }
            menuItem.onClick();
          }}
        >
          {menuItem.title}

      {menuItem.children &&
        menuItemsOpen[menuItem.key] &&
        getExpandedMenuItems(menuItem.children, menuItemsOpen, menuItemOpened, depth + 1)}
    </React.Fragment>
  ));

const getContractedMenuItems = menuItems =>
  menuItems.map(menuItem => (
    <React.Fragment key={menuItem.key}>
      {!menuItem.skipInContractedMenu && ( // just put the children of menu items into the sidebar
        <Button key={menuItem.title} icon={menuItem.icon} onClick={menuItem.onClick} />
      )}
      {menuItem.children && getContractedMenuItems(menuItem.children)}
    </React.Fragment>
  ));

const AppChrome = ({
  headerContent,
  icon,
  content,
  isExpanded,
  menuItems,
  actionBarItems,
  menuItemsOpen,
  menuItemOpened,
  setIsExpanded,
}) => (

      {isExpanded ? (
        <React.Fragment>

            <Button
              aria-label="Show/hide the sidebar"
              size="large"
              color={SIDE_BAR_COLOUR}
              icon="bars"
              onClick={() => setIsExpanded(!isExpanded)}
            />

            {getExpandedMenuItems(menuItems, menuItemsOpen, menuItemOpened)}

        </React.Fragment>
      ) : (
        <Button.Group vertical color={SIDE_BAR_COLOUR}>
          <Button size="large" icon="bars" onClick={() => setIsExpanded(!isExpanded)} />
          {getContractedMenuItems(menuItems)}
        </Button.Group>
      )}

{content}

);

AppChrome.contextTypes = {
  store: PropTypes.object,
  router: PropTypes.shape({
    history: object.isRequired,
  }),
};

AppChrome.propTypes = {
  activeMenuItem: PropTypes.string.isRequired,
  content: PropTypes.object.isRequired,
};

export default enhance(AppChrome);
<|endoftext|>


<commit_before>import $ from 'jquery';
import d3 from 'd3';
import * from 'd3-scale-chromatic';

// Color related utility functions go in this object
export const bnbColors = [
  '#9e0142',
  '#d53e4f',
  '#f46d43',
  '#fdae61',
  '#fee08b',
   '#ffffbf',
  '#e6f598',
  '#abdda4',
  '#66c2a5',
  '#3288bd',
  '#5e4fa2',
  '#8e0152',
  '#c51b7d',
  '#de77ae',
  '#f1b6da',
  '#fde0ef',
  '#f7f7f7',
  '#e6f5d0',
  '#b8e186',
  '#7fbc41',
  '#4d9221',
  '#276419',
];

const spectrums = {
  blue_white_yellow: [
    '#00d1c1',
    'white',
    '#ffb400',
  ],
  fire: [
    'white',
    'yellow',
    'red',
    'black',
  ],
  white_black: [
    'white',
    'black',
  ],
  black_white: [
    'black',
    'white',
  ],
};

export const category21 = (function () {
  // Color factory
  const seen = {};
  return function (s) {
    if (!s) {
      return;
    }
    let stringifyS = String(s);
    // next line is for superset series that should have the same color
    stringifyS = stringifyS.replace('---', '');
    if (seen[stringifyS] === undefined) {
      seen[stringifyS] = Object.keys(seen).length;
    }
    /* eslint consistent-return: 0 */
    /*return bnbColors[seen[stringifyS] % bnbColors.length];*/
    return d3.interpolateSpectral[seen[stringifyS] % seen[stringifyS].length];
  };
}());

export const colorScalerFactory = function (colors, data, accessor) {
  // Returns a linear scaler our of an array of color
  if (!Array.isArray(colors)) {
    /* eslint no-param-reassign: 0 */
    colors = spectrums[colors];
  }
  let ext = [0, 1];
  if (data !== undefined) {
    ext = d3.extent(data, accessor);
  }
  const points = [];
  const chunkSize = (ext[1] - ext[0]) / colors.length;
  $.each(colors, function (i) {
    points.push(i * chunkSize);
  });
  return d3.scale.linear().domain(points).range(colors);
};
<commit_msg>Update colors.js<commit_after>import $ from 'jquery';
import d3 from 'd3';
import * from 'd3-scale-chromatic';

// Color related utility functions go in this object
export const bnbColors = [
  '#9e0142',
  '#d53e4f',
  '#f46d43',
  '#fdae61',
  '#fee08b',
   '#ffffbf',
  '#e6f598',
  '#abdda4',
  '#66c2a5',
  '#3288bd',
  '#5e4fa2',
  '#8e0152',
  '#c51b7d',
  '#de77ae',
  '#f1b6da',
  '#fde0ef',
  '#f7f7f7',
  '#e6f5d0',
  '#b8e186',
  '#7fbc41',
  '#4d9221',
  '#276419',
];

const spectrums = {
  blue_white_yellow: [
    '#00d1c1',
    'white',
    '#ffb400',
  ],
  fire: [
    'white',
    'yellow',
    'red',
    'black',
  ],
  white_black: [
    'white',
    'black',
  ],
  black_white: [
    'black',
    'white',
  ],
};

export const category21 = (function () {
  // Color factory
  const seen = {};
  return function (s) {
    if (!s) {
      return;
    }
    let stringifyS = String(s);
    // next line is for superset series that should have the same color
    stringifyS = stringifyS.replace('---', '');
    if (seen[stringifyS] === undefined) {
      seen[stringifyS] = Object.keys(seen).length;
    }
    /* eslint consistent-return: 0 */
    return bnbColors[seen[stringifyS] % bnbColors.length];
    /*return d3.interpolateSpectral[seen[stringifyS] % seen[stringifyS].length];*/
  };
}());

export const colorScalerFactory = function (colors, data, accessor) {
  // Returns a linear scaler our of an array of color
  if (!Array.isArray(colors)) {
    /* eslint no-param-reassign: 0 */
    colors = spectrums[colors];
  }
  let ext = [0, 1];
  if (data !== undefined) {
    ext = d3.extent(data, accessor);
  }
  const points = [];
  const chunkSize = (ext[1] - ext[0]) / colors.length;
  $.each(colors, function (i) {
    points.push(i * chunkSize);
  });
  return d3.scale.linear().domain(points).range(colors);
};
<|endoftext|>


<commit_before>const homepage = '.c-homepage';
const statusBarInfo = '.c-straatbeeld-status-bar__info-item';
const straatbeeld = '.c-straatbeeld';

describe('panorama module', () => {
  beforeEach(() => {
    cy.server();
    cy.route('/panorama/panoramas/*/adjacencies/?newest_in_range=true&mission_type=bi').as('getResults');

    // go to the homepage
    cy.visit('/');
    // the homepage should be visible
    cy.get(homepage).should('be.visible');
    // check if the link is in the dom and visible
    cy.get('.qa-straatbeeld-link').should('exist').and('be.visible');
    // the straatbeeld should not exist yet
    cy.get(straatbeeld).should('not.exist');
    // click on the link to go to the map
    cy.get('.qa-straatbeeld-link').click();

    cy.wait('@getResults');
  });

  describe('user should be able to navigate to the panoram from the homepage', () => {
    it('should open the panorama viewer', () => {
      // the homepage should not be visible anymore
      cy.get(homepage).should('not.be.visible');
      // the map should be visible
      cy.get(straatbeeld).should('exist').and('be.visible');
    });
  });

  describe('user should be able to use the panorama viewer', () => {
    it('should be able to click a hotspot and change the coordinates', () => {
      cy.get(statusBarInfo).first()
      .then((coordinatesEl) => {
        const coordinates = coordinatesEl[0].innerText;

        cy.get(statusBarInfo).first()
          .contains(coordinates)
          .should('exist');

        // the click the first hotspot
        cy.get('.qa-hotspot-button:visible').first().click();

        cy.wait('@getResults');
        // the coordinates should be different
        cy.get(statusBarInfo).first()
          .contains(coordinates)
          .should('not.exist');
      });
    });
  });

  describe('user should be able to use the leaflet map', () => {
    it('should render the leaflet map and set the marker', () => {
      // the canvas inside de marzipano viewer should exist and be visible
      cy.get('.leaflet-marker-pane').find('img').should('exist').and('be.visible');
    });

    it('should set the panoramabeelden as active layers in the map-panel legenda', () => {
      // open the the map panel (closed initially)
      cy.get('.map-panel__toggle').click();
      // should contain the correct value
      cy.get('.map-legend__category-title')
        .contains('Panoramabeelden')
        .should('exist').and('be.visible');
    });

    it('should set the layers in the leaflet map', () => {
      // should contain the correct value
      cy.get('.leaflet-image-layer').should('exist').and('be.visible');
    });

    it('should change the coordinates when clicked on the map', () => {
      cy.get(statusBarInfo).first()
      .then((coordinatesEl) => {
        const coordinates = coordinatesEl[0].innerText;

        cy.get(statusBarInfo).first()
          .contains(coordinates)
          .should('exist');

        // click on the leaflet map with a different position
        cy.get('.leaflet-container').trigger('click', 20, 100);

        cy.wait('@getResults');
        // the coordinates should be different
        cy.get(statusBarInfo).first()
          .contains(coordinates)
          .should('not.exist');
      });
    });
  });

  describe('user should be able to interact with the panorama', () => {
    it('should remember the state when closing the pano, and update to search results when clicked in map', () => {
      const panoUrl = '/#?dte=bag%2Fopenbareruimte%2F03630000004153%2F&mpb=topografie&mpz=11&mpo=pano::T&mpv=52.3663002:4.883519&sbf=Cu&sbh=qQ&sbi=TMX7316010203-000714_pano_0001_002608&sbl=ZREfS:3IuGM&sbln=pano&sblb=Meest%2520recent';
      let newUrl;

      cy.defineGeoSearchRoutes();
      // TODO: enable this (getTypeAhead) once fetch is supported by Cypress
      // https://github.com/cypress-io/cypress/issues/95
      cy.route('/bag/openbareruimte/*').as('getOpenbareRuimte');
      cy.route('/panorama/thumbnail/*').as('getPanoThumbnail');

      cy.viewport(1000, 660);
      cy.get('.leaflet-marker-pane').find('img').should('exist').and('be.visible');
      cy.get('#auto-suggest__input').type('lei');

      // TODO: remove wait(500) and enable the route-wait (DP-6088)
      cy.wait(500);
      cy.get('.auto-suggest').contains('Leidsegracht').click();

      cy.wait('@getOpenbareRuimte');
      cy.wait('@getPanoThumbnail');
      cy.get('img.c-straatbeeld-thumbnail--img').should('exist').and('be.visible');
      cy.get('h2.qa-title').should('exist').and('be.visible').contains('Leidsegracht');
      cy.get('img.c-straatbeeld-thumbnail--img').click();

      cy.wait('@getResults');
      cy.location().then((loc) => {
        newUrl = loc.pathname + loc.hash;
        expect(newUrl).to.equal(panoUrl);
      });

      let largestButtonSize = 0;
      let largestButton;
      cy.get('.qa-hotspot-rotation:visible').each((button) => {
        // get largest (e.g. closest by) navigation button
        cy.wrap(button).should('have.css', 'width').then((width) => {
          if (parseInt(width.replace('px', ''), 10) > largestButtonSize) {
            largestButtonSize = parseInt(width.replace('px', ''), 10);
            largestButton = button;
          }
        });
      }).then(() => {
        largestButton.click();
      });

      cy.wait('@getResults');
      // verify that something happened by comparing the url
      cy.location().then((loc) => {
        newUrl = loc.pathname + loc.hash;
        expect(newUrl).not.to.equal(panoUrl);
      });

      cy.get('button.c-straatbeeld__close').click();
      cy.get('img.c-straatbeeld-thumbnail--img').should('exist').and('be.visible');
      cy.get('h2.qa-title').should('exist').and('be.visible').contains('Leidsegracht');
      cy.get('img.c-straatbeeld-thumbnail--img').click();

      cy.get('.leaflet-container').click(20, 100);

      cy.wait('@getResults');
      // verify that something happened by comparing the url
      cy.location().then((loc) => {
        const thisUrl = loc.pathname + loc.hash;
        expect(thisUrl).not.to.equal(newUrl);
      });
      cy.get('button.c-straatbeeld__close').click();

      cy.waitForGeoSearch();
      cy.get('h1.o-header__title').contains('Resultaten').should('exist').and('be.visible');
      cy.get('h2').contains('Openbare ruimte').should('exist').and('be.visible');
    });
  });
});
<commit_msg>fix e2e pano<commit_after>const homepage = '.c-homepage';
const statusBarInfo = '.c-straatbeeld-status-bar__info-item';
const straatbeeld = '.c-straatbeeld';

describe('panorama module', () => {
  beforeEach(() => {
    cy.server();
    cy.route('/panorama/panoramas/*/adjacencies/?newest_in_range=true&mission_type=bi').as('getResults');

    // go to the homepage
    cy.visit('/');
    // the homepage should be visible
    cy.get(homepage).should('be.visible');
    // check if the link is in the dom and visible
    cy.get('.qa-straatbeeld-link').should('exist').and('be.visible');
    // the straatbeeld should not exist yet
    cy.get(straatbeeld).should('not.exist');
    // click on the link to go to the map
    cy.get('.qa-straatbeeld-link').click();

    cy.wait('@getResults');
  });

  describe('user should be able to navigate to the panoram from the homepage', () => {
    it('should open the panorama viewer', () => {
      // the homepage should not be visible anymore
      cy.get(homepage).should('not.be.visible');
      // the map should be visible
      cy.get(straatbeeld).should('exist').and('be.visible');
    });
  });

  describe('user should be able to use the panorama viewer', () => {
    it('should be able to click a hotspot and change the coordinates', () => {
      cy.get(statusBarInfo).first()
      .then((coordinatesEl) => {
        const coordinates = coordinatesEl[0].innerText;

        cy.get(statusBarInfo).first()
          .contains(coordinates)
          .should('exist');

        // the click the first hotspot
        cy.get('.qa-hotspot-button:visible').first().click();

        cy.wait('@getResults');
        // the coordinates should be different
        cy.get(statusBarInfo).first()
          .contains(coordinates)
          .should('not.exist');
      });
    });
  });

  describe('user should be able to use the leaflet map', () => {
    it('should render the leaflet map and set the marker', () => {
      // the canvas inside de marzipano viewer should exist and be visible
      cy.get('.leaflet-marker-pane').find('img').should('exist').and('be.visible');
    });

    it('should set the panoramabeelden as active layers in the map-panel legenda', () => {
      // open the the map panel (closed initially)
      cy.get('.map-panel__toggle').click();
      // should contain the correct value
      cy.get('.map-legend__category-title')
        .contains('Panoramabeelden')
        .should('exist').and('be.visible');
    });

    it('should set the layers in the leaflet map', () => {
      // should contain the correct value
      cy.get('.leaflet-image-layer').should('exist').and('be.visible');
    });

    it('should change the coordinates when clicked on the map', () => {
      cy.get(statusBarInfo).first()
      .then((coordinatesEl) => {
        const coordinates = coordinatesEl[0].innerText;

        cy.get(statusBarInfo).first()
          .contains(coordinates)
          .should('exist');

        // click on the leaflet map with a different position
        cy.get('.leaflet-container').trigger('click', 20, 100);

        cy.wait('@getResults');
        // the coordinates should be different
        cy.get(statusBarInfo).first()
          .contains(coordinates)
          .should('not.exist');
      });
    });
  });

  describe('user should be able to interact with the panorama', () => {
    it('should remember the state when closing the pano, and update to search results when clicked in map', () => {
      const panoUrl = '/#?dte=bag%2Fopenbareruimte%2F03630000004153%2F&mpb=topografie&mpz=11&mpo=pano::T&mpv=52.3663002:4.883519&sbf=Cu&sbh=qQ&sbi=TMX7316010203-000714_pano_0001_002608&sbl=ZREfS:3IuGM&sbmt=bi&sbln=pano&sblb=Meest%2520recent';
      let newUrl;

      cy.defineGeoSearchRoutes();
      // TODO: enable this (getTypeAhead) once fetch is supported by Cypress
      // https://github.com/cypress-io/cypress/issues/95
      cy.route('/bag/openbareruimte/*').as('getOpenbareRuimte');
      cy.route('/panorama/thumbnail/*').as('getPanoThumbnail');

      cy.viewport(1000, 660);
      cy.get('.leaflet-marker-pane').find('img').should('exist').and('be.visible');
      cy.get('#auto-suggest__input').type('lei');

      // TODO: remove wait(500) and enable the route-wait (DP-6088)
      cy.wait(500);
      cy.get('.auto-suggest').contains('Leidsegracht').click();

      cy.wait('@getOpenbareRuimte');
      cy.wait('@getPanoThumbnail');
      cy.get('img.c-straatbeeld-thumbnail--img').should('exist').and('be.visible');
      cy.get('h2.qa-title').should('exist').and('be.visible').contains('Leidsegracht');
      cy.get('img.c-straatbeeld-thumbnail--img').click();

      cy.wait('@getResults');
      cy.location().then((loc) => {
        newUrl = loc.pathname + loc.hash;
        expect(newUrl).to.equal(panoUrl);
      });

      let largestButtonSize = 0;
      let largestButton;
      cy.get('.qa-hotspot-rotation:visible').each((button) => {
        // get largest (e.g. closest by) navigation button
        cy.wrap(button).should('have.css', 'width').then((width) => {
          if (parseInt(width.replace('px', ''), 10) > largestButtonSize) {
            largestButtonSize = parseInt(width.replace('px', ''), 10);
            largestButton = button;
          }
        });
      }).then(() => {
        largestButton.click();
      });

      cy.wait('@getResults');
      // verify that something happened by comparing the url
      cy.location().then((loc) => {
        newUrl = loc.pathname + loc.hash;
        expect(newUrl).not.to.equal(panoUrl);
      });

      cy.get('button.c-straatbeeld__close').click();
      cy.get('img.c-straatbeeld-thumbnail--img').should('exist').and('be.visible');
      cy.get('h2.qa-title').should('exist').and('be.visible').contains('Leidsegracht');
      cy.get('img.c-straatbeeld-thumbnail--img').click();

      cy.get('.leaflet-container').click(20, 100);

      cy.wait('@getResults');
      // verify that something happened by comparing the url
      cy.location().then((loc) => {
        const thisUrl = loc.pathname + loc.hash;
        expect(thisUrl).not.to.equal(newUrl);
      });
      cy.get('button.c-straatbeeld__close').click();

      cy.waitForGeoSearch();
      cy.get('h1.o-header__title').contains('Resultaten').should('exist').and('be.visible');
      cy.get('h2').contains('Openbare ruimte').should('exist').and('be.visible');
    });
  });
});
<|endoftext|>


<commit_before>define([],function(BaseLayout){
	'use strict';
	return Backbone.Router.extend({
		initialize: function () {

		}
	});
});<commit_msg>small router fix<commit_after>define(['backbone'],function(){
	'use strict';
	return Backbone.Router.extend({
		initialize: function () {

		}
	});
});<|endoftext|>


<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
(function(){
    // jQuery Loading into electron
    window.$ = window.jQuery = require('./js/jquery.min.js');

    var logs = [];

    $( document ).ajaxError(function( event, request, settings ) {
        if (logs.length > 1) {
            logs.splice(0, 1);
        }
        logs.push({'type':'ERROR', 'timeStamp':event.timeStamp, 'url': settings.url});
    });

    var app = angular.module('viewer', ['ui.layout'])
        .controller('ClusterController', function($scope, $interval) {
            this.clusters = [];
            this.placeHolder = '192.168.99.100:8088';
            this.ip = this.placeHolder;
            this.selected = -1;
            this.logs = logs;

            var clusters = this.clusters;

            this.add = function() {
                this.clusters.push({
                    ip: this.ip,
                    name: this.ip.split(':')[0],
                    racks: {}
                });
                this.ip = this.placeHolder;
            };

            this.select = function(i) {
                this.selected = i;
                updateNodes(this.clusters[this.selected]);
            };

            this.delete = function(i) {
                this.clusters.splice(i, 1);
                if (this.selected == i) {
                    this.selected = this.clusters.length - 1;
                    if (this.selected >= 0) {
                        updateNodes(this.clusters[this.selected]);
                    }
                }
            };

            this.getSelected = function() {
                return this.clusters[this.selected];
            };

            this.getNumberOfNodes = function() {
                var count = 0;
                if (this.selected >= 0) {
                    for (var rack in this.getSelected().racks) {
                        count += rack.length;
                    }
                }
                return count;
            };

            this.getTotalNumberOfNodes = function() {
                var count = 0;
                this.clusters.forEach(function(cluster,index,array) {
                    for (var rack in cluster.racks) {
                        count += cluster.racks[rack].length;
                    }
                });
                return count;
            };

            var updateCluster = function(cluster) {
                if (cluster.ip.endsWith('8088')) {
                    $.get('http://' + cluster.ip + '/ws/v1/cluster', '', function(data) {
                        var info = data['clusterInfo'];
                        cluster.resourceManagerType = 'YARN';
                        cluster.resourceManagerVersion = info['resourceManagerVersion'];
                        cluster.startedOn = ((new Date() - info['startedOn'])/1000 | 0);
                        cluster.state = info['state'];
                        cluster.haState = info['haState'];
                        cluster.color = 'ghostwhite';
                        updateNodes(cluster);
                    }).fail(function() {
                        cluster.state = 'Disconnected';
                    });
                } else if (cluster.ip.endsWith('5050')) {
                    $.get('http://' + cluster.ip + '/master/state.json', '', function(data) {
                        cluster.resourceManagerType = 'MESOS';
                        cluster.resourceManagerVersion = data['version'];
                        cluster.startedOn = ((new Date() - data['start_time'])/1000 | 0);
                        cluster.state = 'STARTED';
                        cluster.haState = 'Unknown';
                        cluster.racks = {};
                        cluster.color = 'aliceblue';
                        data['slaves'].forEach(function(node) {
                            node['rack'] = '/default-rack';
                            if (!(node['rack'] in cluster.racks)) {
                                cluster.racks[node['rack']] = [];
                            }
                            cluster.racks[node['rack']].push({
                                rack: '/default-rack',
                                hostName: node['hostname'],
                                state: node['active'] ? 'RUNNING' : 'INACTIVE',
                                core: node['resources'].cpus,
                                usedCore: node['used_resources'].cpus,
                                mem: node['resources'].mem,
                                usedMem: node['used_resources'].mem
                            });
                        })
                    }).fail(function() {
                        cluster.state = 'Disconnected';
                    });
                }
            };

            var updateNodes = function(cluster) {
                if (cluster.ip.endsWith('8088')) {
                    $.get('http://' + cluster.ip + '/ws/v1/cluster/nodes', '', function(data) {
                        cluster.racks = {};
                        data['nodes']['node'].forEach(function(node) {
                            if (!(node['rack'] in cluster.racks)) {
                                cluster.racks[node['rack']] = [];
                            }
                            cluster.racks[node['rack']].push({
                                rack: node['rack'],
                                hostName: node['nodeHostName'],
                                state: node['state'],
                                core: node['availableVirtualCores'],
                                usedCore: node['usedVirtualCores']+1,
                                mem: node['availMemoryMB'],
                                usedMem: node['usedMemoryMB']+10240
                            });
                        })
                    }).error(function() {
                        cluster.racks = {};
                    });
                } else if (cluster.ip.endsWith('5050')) {
                    // already done.
                }
            };

            $scope.updateClusters = function() {
                clusters.forEach(updateCluster);
            };
            $interval(function() { $scope.updateClusters(); }, 2000);
        })
        .directive('clusterList', function() {
            return {
                restrict: 'E',
                templateUrl: 'templates/cluster-list.html'
            };
        })
        .directive('nodeList', function() {
            return {
                restrict: 'E',
                templateUrl: 'templates/node-list.html'
            };
        })
        .directive('logList', function() {
            return {
                restrict: 'E',
                templateUrl: 'templates/log-list.html'
            };
        });
    app.filter('secondsToDateTime', [function() {
        return function(seconds) {
            return new Date(1970, 0, 1).setSeconds(seconds);
        };
    }]);
})();
<commit_msg>Fix getNumberOfNodes()<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
(function(){
    // jQuery Loading into electron
    window.$ = window.jQuery = require('./js/jquery.min.js');

    var logs = [];

    $( document ).ajaxError(function( event, request, settings ) {
        if (logs.length > 1) {
            logs.splice(0, 1);
        }
        logs.push({'type':'ERROR', 'timeStamp':event.timeStamp, 'url': settings.url});
    });

    var app = angular.module('viewer', ['ui.layout'])
        .controller('ClusterController', function($scope, $interval) {
            this.clusters = [];
            this.placeHolder = '192.168.99.100:8088';
            this.ip = this.placeHolder;
            this.selected = -1;
            this.logs = logs;

            var clusters = this.clusters;

            this.add = function() {
                this.clusters.push({
                    ip: this.ip,
                    name: this.ip.split(':')[0],
                    racks: {}
                });
                this.ip = this.placeHolder;
            };

            this.select = function(i) {
                this.selected = i;
                updateNodes(this.clusters[this.selected]);
            };

            this.delete = function(i) {
                this.clusters.splice(i, 1);
                if (this.selected == i) {
                    this.selected = this.clusters.length - 1;
                    if (this.selected >= 0) {
                        updateNodes(this.clusters[this.selected]);
                    }
                }
            };

            this.getSelected = function() {
                return this.clusters[this.selected];
            };

            this.getNumberOfNodes = function() {
                var count = 0;
                if (this.selected >= 0) {
                    for (var rack in this.getSelected().racks) {
                        count += this.getSelected().racks[rack].length;
                    }
                }
                return count;
            };

            this.getTotalNumberOfNodes = function() {
                var count = 0;
                this.clusters.forEach(function(cluster,index,array) {
                    for (var rack in cluster.racks) {
                        count += cluster.racks[rack].length;
                    }
                });
                return count;
            };

            var updateCluster = function(cluster) {
                if (cluster.ip.endsWith('8088')) {
                    $.get('http://' + cluster.ip + '/ws/v1/cluster', '', function(data) {
                        var info = data['clusterInfo'];
                        cluster.resourceManagerType = 'YARN';
                        cluster.resourceManagerVersion = info['resourceManagerVersion'];
                        cluster.startedOn = ((new Date() - info['startedOn'])/1000 | 0);
                        cluster.state = info['state'];
                        cluster.haState = info['haState'];
                        cluster.color = 'ghostwhite';
                        updateNodes(cluster);
                    }).fail(function() {
                        cluster.state = 'Disconnected';
                    });
                } else if (cluster.ip.endsWith('5050')) {
                    $.get('http://' + cluster.ip + '/master/state.json', '', function(data) {
                        cluster.resourceManagerType = 'MESOS';
                        cluster.resourceManagerVersion = data['version'];
                        cluster.startedOn = ((new Date() - data['start_time'])/1000 | 0);
                        cluster.state = 'STARTED';
                        cluster.haState = 'Unknown';
                        cluster.racks = {};
                        cluster.color = 'aliceblue';
                        data['slaves'].forEach(function(node) {
                            node['rack'] = '/default-rack';
                            if (!cluster.racks.hasOwnProperty(node['rack'])) {
                                cluster.racks[node['rack']] = [];
                            }
                            cluster.racks[node['rack']].push({
                                rack: node['rack'],
                                hostName: node['hostname'],
                                state: node['active'] ? 'RUNNING' : 'INACTIVE',
                                core: node['resources'].cpus,
                                usedCore: node['used_resources'].cpus,
                                mem: node['resources'].mem,
                                usedMem: node['used_resources'].mem
                            });
                        })
                    }).fail(function() {
                        cluster.state = 'Disconnected';
                    });
                }
            };

            var updateNodes = function(cluster) {
                if (cluster.ip.endsWith('8088')) {
                    $.get('http://' + cluster.ip + '/ws/v1/cluster/nodes', '', function(data) {
                        cluster.racks = {};
                        data['nodes']['node'].forEach(function(node) {
                            if (!(node['rack'] in cluster.racks)) {
                                cluster.racks[node['rack']] = [];
                            }
                            cluster.racks[node['rack']].push({
                                rack: node['rack'],
                                hostName: node['nodeHostName'],
                                state: node['state'],
                                core: node['availableVirtualCores'],
                                usedCore: node['usedVirtualCores']+1,
                                mem: node['availMemoryMB'],
                                usedMem: node['usedMemoryMB']+10240
                            });
                        })
                    }).error(function() {
                        cluster.racks = {};
                    });
                } else if (cluster.ip.endsWith('5050')) {
                    // already done.
                }
            };

            $scope.updateClusters = function() {
                clusters.forEach(updateCluster);
            };
            $interval(function() { $scope.updateClusters(); }, 2000);
        })
        .directive('clusterList', function() {
            return {
                restrict: 'E',
                templateUrl: 'templates/cluster-list.html'
            };
        })
        .directive('nodeList', function() {
            return {
                restrict: 'E',
                templateUrl: 'templates/node-list.html'
            };
        })
        .directive('logList', function() {
            return {
                restrict: 'E',
                templateUrl: 'templates/log-list.html'
            };
        });
    app.filter('secondsToDateTime', [function() {
        return function(seconds) {
            return new Date(1970, 0, 1).setSeconds(seconds);
        };
    }]);
})();
<|endoftext|>