<commit_before>var Page1Ctrl, app;

app = angular.module('twf');

Page1Ctrl = function ($scope, $timeout, getGame, postGame, $routeParams) {
    $scope.title = "Hello, page1!";
    $scope.currentCategory = 0;

    getGame.get(function (data) {
        $scope.description = data.description;
        console.log(data);
        $scope.categories = data.tile_sets;
        $scope.tiles = data.tile_sets[$scope.currentCategory].tiles;

        $scope.data = data;
        $timeout(function () {
            DraggModule.makeDraggable();
        });
    }, $routeParams.id);
    $scope.openPopup = function ($event) {
        TweenMax.to($(event.target), 0.2, {opacity: 0, ease: Linear.easeNone});
        TweenMax.to($(event.target).parent(), 0.6, {scale: 40, x: 900, y: 900, z: -20, ease: Linear.easeNone});
        TweenMax.to($(".task-popup"), 1, {opacity: 1, ease: Linear.easeNone, delay: 0.5});
        TweenMax.to($(".task-popup"), 1, {css: {zIndex: 1000}, ease: Linear.easeNone, delay: 0.5});
        TweenMax.to($(event.target), 1, {opacity: 1, ease: Linear.easeNone, delay: 2});
    };
    $scope.closePopup = function ($event) {
        TweenMax.to($(".task-popup"), 0.6, {opacity: 0, ease: Linear.easeNone});
        TweenMax.to($(".task-popup"), 0.6, {css: {zIndex: -1}, ease: Linear.easeNone});
        TweenMax.to($(".open-popup"), 0.6, {scale: 1, x: 01, y: 0, z: 0, ease: Linear.easeNone});
    };
    $scope.playSound = function ($event) {
        $(event.target).parent().speak();
    };
    $scope.switchCategory = function($event) {
        var id = $(event.target).attr("id");
        $scope.currentCategory = id;
        $scope.tiles = $scope.data.tile_sets[$scope.currentCategory].tiles;
    };
    $scope.finishGame = function ($event) {
        postGame.post(function (data) {
            console.log(data);
            TweenMax.to($(".rating-popup"), 1, {opacity: 1, ease: Linear.easeNone});
            TweenMax.to($(".rating-popup"), 1, {css: {zIndex: 1000}, ease: Linear.easeNone,});
        });
    }
};

app.controller('Page1Ctrl', ['$scope', '$timeout', 'getGame', 'postGame', '$routeParams', Page1Ctrl]);

<commit_msg>play stop propagation<commit_after>var Page1Ctrl, app;

app = angular.module('twf');

Page1Ctrl = function ($scope, $timeout, getGame, postGame, $routeParams) {
    $scope.title = "Hello, page1!";
    $scope.currentCategory = 0;

    getGame.get(function (data) {
        $scope.description = data.description;
        console.log(data);
        $scope.categories = data.tile_sets;
        $scope.tiles = data.tile_sets[$scope.currentCategory].tiles;

        $scope.data = data;
        $timeout(function () {
            DraggModule.makeDraggable();
        });
    }, $routeParams.id);
    $scope.openPopup = function ($event) {
        TweenMax.to($(event.target), 0.2, {opacity: 0, ease: Linear.easeNone});
        TweenMax.to($(event.target).parent(), 0.6, {scale: 40, x: 900, y: 900, z: -20, ease: Linear.easeNone});
        TweenMax.to($(".task-popup"), 1, {opacity: 1, ease: Linear.easeNone, delay: 0.5});
        TweenMax.to($(".task-popup"), 1, {css: {zIndex: 1000}, ease: Linear.easeNone, delay: 0.5});
        TweenMax.to($(event.target), 1, {opacity: 1, ease: Linear.easeNone, delay: 2});
    };
    $scope.closePopup = function ($event) {
        TweenMax.to($(".task-popup"), 0.6, {opacity: 0, ease: Linear.easeNone});
        TweenMax.to($(".task-popup"), 0.6, {css: {zIndex: -1}, ease: Linear.easeNone});
        TweenMax.to($(".open-popup"), 0.6, {scale: 1, x: 01, y: 0, z: 0, ease: Linear.easeNone});
    };
    $scope.playSound = function ($event) {
        $(event.target).parent().speak();
        event.stopPropagation();
    };
    $scope.switchCategory = function($event) {
        var id = $(event.target).attr("id");
        $scope.currentCategory = id;
        $scope.tiles = $scope.data.tile_sets[$scope.currentCategory].tiles;
    };
    $scope.finishGame = function ($event) {
        postGame.post(function (data) {
            console.log(data);
            TweenMax.to($(".rating-popup"), 1, {opacity: 1, ease: Linear.easeNone});
            TweenMax.to($(".rating-popup"), 1, {css: {zIndex: 1000}, ease: Linear.easeNone,});
        });
    }
};

app.controller('Page1Ctrl', ['$scope', '$timeout', 'getGame', 'postGame', '$routeParams', Page1Ctrl]);

<|endoftext|>


<commit_before>// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file.
//
// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery
//= require jquery_ujs
//= require twitter/bootstrap
//= require_tree ./vendor/jQuery-Knob-master/js
//= require spin
//= require ladda
//= require deathstar/test_session
<commit_msg>We need to move this.<commit_after>// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file.
//
// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery
//= require jquery_ujs
//= require twitter/bootstrap
//= require spin
//= require ladda
//= require deathstar/test_session
<|endoftext|>


<commit_before>angular.module("OpenHq").directive("humanTime", function() {
    return {
        restrict: "E",
        scope: {
          datetime: '=',
        },
        template: "{{ datetime }}",
        link: function($scope, el){
            $scope.$watch('datetime', function(){
                $(el).find('abbr').timeago();
            });
        },
    };
});<commit_msg>Bugfix for first human_time not loading<commit_after>angular.module("OpenHq").directive("humanTime", function() {
  return {
    restrict: "E",
    scope: {
      datetime: '=',
    },
    template: "{{ datetime }}",
    link: function($scope, el){
      $scope.$watch('datetime', function(){
        if ($scope.datetime) $(el).find('abbr').timeago();
      });
    },
  };
});
<|endoftext|>


<commit_before>Maildog.Views.ShowEmailThread = Backbone.CompositeView.extend({
  template: JST['showEmailThread'],

  initialize: function() {
    this.listenTo(this.collection, "reset", this.render);
    this.listenTo(this.collection, "add", this._addSubviewToEmail);
    Backbone.pubSub.on("deleteThread", this.deleteThread, this);
  },

  events: {
    "click .reply-forward-email-box": "addReplyForwardView",
    "submit": "returnBox"
  },

  render: function() {
    this.collection.forEach(this._addSubviewToEmail.bind(this));
    this.$el.html(this.template());
    this.attachSubviews();
    return this;
  },

  deleteThread: function() {
    this.collection.destroy({
      success: function() {
        Backbone.history.navigate("#", { trigger: true })
        Maildog.router.addFlash("Email conversation deleted");
      }
    });
  },

  addReplyForwardView: function() {
    var subview = new Maildog.Views.ReplyForwardEmailBox({
      parentEmail: this.collection.last(),
      originalEmail: this.collection.first(),
      recipient: this.collection.replyTo(),
      collection: this.collection
    });
    $('.reply-forward-email-box').addClass('invisible');
    this.addSubview(".reply-forward-email-section", subview);
  },

  returnBox: function(e) {
    e.preventDefault()
    $('.reply-forward-email-box').removeClass('invisible');
  },

  _addSubviewToEmail: function(email) {
    var subview = new Maildog.Views.EmailShow({
      model: email
    });
    this.addSubview(".email-thread-list", subview);
  }
});
<commit_msg>add focus to reply email textarea<commit_after>Maildog.Views.ShowEmailThread = Backbone.CompositeView.extend({
  template: JST['showEmailThread'],

  initialize: function() {
    this.listenTo(this.collection, "reset", this.render);
    this.listenTo(this.collection, "add", this._addSubviewToEmail);
    Backbone.pubSub.on("deleteThread", this.deleteThread, this);
  },

  events: {
    "click .reply-forward-email-box": "addReplyForwardView",
    "submit": "returnBox"
  },

  render: function() {
    this.collection.forEach(this._addSubviewToEmail.bind(this));
    this.$el.html(this.template());
    this.attachSubviews();
    return this;
  },

  deleteThread: function() {
    this.collection.destroy({
      success: function() {
        Backbone.history.navigate("#", { trigger: true })
        Maildog.router.addFlash("Email conversation deleted");
      }
    });
  },

  addReplyForwardView: function() {
    var subview = new Maildog.Views.ReplyForwardEmailBox({
      parentEmail: this.collection.last(),
      originalEmail: this.collection.first(),
      recipient: this.collection.replyTo(),
      collection: this.collection
    });
    $('.reply-forward-email-box').addClass('invisible');
    this.addSubview(".reply-forward-email-section", subview);
    $('textarea').focus()
  },

  returnBox: function(e) {
    e.preventDefault()
    $('.reply-forward-email-box').removeClass('invisible');
  },

  _addSubviewToEmail: function(email) {
    var subview = new Maildog.Views.EmailShow({
      model: email
    });
    this.addSubview(".email-thread-list", subview);
  }
});
<|endoftext|>


<commit_before>import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import config from '../config';

const defaultState = {
  fetchedParams: false,
  fetchingParams: false,
  paramError: null,
  parameters: null,
};

export const ParameterContext = React.createContext([{}, () => {}]);

export function ParameterProvider(props) {
  const [
    { fetchedParams, fetchingParams, paramError, parameters },
    setState,
  ] = useState(defaultState);

  useEffect(() => {
    const fetchData = () => {
      setState(state => ({ ...state, fetchingParams: true, paramError: null }));

      fetch(`${config.api}/parameters`)
        .then(response => {
          if (response.status >= 400) {
            throw new paramError('Bad response');
          }
          return response.json();
        })
        .then(
          json => {
            setState(state => ({
              ...state,
              fetchedParams: true,
              fetchingParams: false,
              parameters: json.results,
            }));
          },
          e => {
            console.log('e', e);
            setState(state => ({
              ...state,
              fetchedParams: true,
              fetchingParams: false,
              paramError: e,
            }));
          }
        );
    };

    fetchData();

    return () => {
      setState(defaultState);
    };
  }, []);

  const isCore = function (activeParameterId) {
    return parameters && activeParameterId
      ? parameters.find(p => p.id === activeParameterId).isCore
      : false;
  };

  return (
    <ParameterContext.Provider
      value={{ fetchedParams, fetchingParams, paramError, parameters, isCore }}
    >
      {props.children}
    </ParameterContext.Provider>
  );
}
ParameterProvider.propTypes = {
  children: PropTypes.node,
};
<commit_msg>adding the necessary check<commit_after>import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import config from '../config';

const defaultState = {
  fetchedParams: false,
  fetchingParams: false,
  paramError: null,
  parameters: null,
};

export const ParameterContext = React.createContext([{}, () => {}]);

export function ParameterProvider(props) {
  const [
    { fetchedParams, fetchingParams, paramError, parameters },
    setState,
  ] = useState(defaultState);

  useEffect(() => {
    const fetchData = () => {
      setState(state => ({ ...state, fetchingParams: true, paramError: null }));

      fetch(`${config.api}/parameters`)
        .then(response => {
          if (response.status >= 400) {
            throw new paramError('Bad response');
          }
          return response.json();
        })
        .then(
          json => {
            setState(state => ({
              ...state,
              fetchedParams: true,
              fetchingParams: false,
              parameters: json.results,
            }));
          },
          e => {
            console.log('e', e);
            setState(state => ({
              ...state,
              fetchedParams: true,
              fetchingParams: false,
              paramError: e,
            }));
          }
        );
    };

    fetchData();

    return () => {
      setState(defaultState);
    };
  }, []);

  const isCore = function (activeParameterId) {
    return parameters
      ? parameters.find(p => p.id === activeParameterId)?.isCore
      : false;
  };

  return (
    <ParameterContext.Provider
      value={{ fetchedParams, fetchingParams, paramError, parameters, isCore }}
    >
      {props.children}
    </ParameterContext.Provider>
  );
}
ParameterProvider.propTypes = {
  children: PropTypes.node,
};
<|endoftext|>


<commit_before>'use strict';
import React, { PropTypes as T } from 'react';
import { hashHistory, Link } from 'react-router';
import { connect } from 'react-redux';

import {
  invalidateProjectItem,
  fetchProjectItem,
  patchProject,
  deleteProject,
  showGlobalLoading,
  hideGlobalLoading,
  fetchProjectScenarios,
  resetProjectFrom,
  postScenario
} from '../actions';
import { prettyPrint } from '../utils/utils';
import { t, getLanguage } from '../utils/i18n';
import { fileTypesMatrix } from '../utils/constants';
import config from '../config';

import Breadcrumb from '../components/breadcrumb';
import ProjectFormModal from '../components/project/project-form-modal';
import ProjectHeaderActions from '../components/project/project-header-actions';
import ScenarioCreateModal from '../components/scenario/scenario-create-modal';

var ProjectPageActive = React.createClass({

  propTypes: {
    _invalidateProjectItem: T.func,
    _fetchProjectItem: T.func,
    _patchProject: T.func,
    _deleteProject: T.func,
    _resetProjectFrom: T.func,
    _showGlobalLoading: T.func,
    _hideGlobalLoading: T.func,
    _fetchProjectScenarios: T.func,
    _postScenario: T.func,

    params: T.object,
    project: T.object,
    scenarios: T.object,
    projectForm: T.object,
    scenarioForm: T.object
  },

  getInitialState: function () {
    return {
      projectFormModal: false,
      scenarioCreateModal: false
    };
  },

  // Flag variables to wait for the project and scenario to load.
  projectLoaded: false,
  scenarioLoaded: false,
  loadingVisible: false,

  showLoading: function () {
    this.loadingVisible = true;
    this.props._showGlobalLoading();
  },

  hideLoading: function () {
    this.loadingVisible = false;
    this.props._hideGlobalLoading();
  },

  closeModal: function (what) {
    switch (what) {
      case 'project-form':
        this.setState({projectFormModal: false});
        break;
      case 'new-scenario':
        this.setState({scenarioCreateModal: false});
        break;
    }
  },

  onProjectAction: function (what, event) {
    event.preventDefault();

    switch (what) {
      case 'edit':
        this.setState({projectFormModal: true});
        break;
      case 'delete':
        this.showLoading();
        this.props._deleteProject(this.props.params.projectId);
        break;
      case 'new-scenario':
        this.setState({scenarioCreateModal: true});
        break;
      default:
        throw new Error(`Project action not implemented: ${what}`);
    }
  },

  componentDidMount: function () {
    this.projectLoaded = false;
    this.scenarioLoaded = false;
    this.showLoading();
    this.props._fetchProjectItem(this.props.params.projectId);
    this.props._fetchProjectScenarios(this.props.params.projectId);
  },

  componentWillUnmount: function () {
    this.props._invalidateProjectItem();
  },

  componentWillReceiveProps: function (nextProps) {
    if (this.props.project.fetching && !nextProps.project.fetching) {
      this.projectLoaded = true;
    }
    if (this.props.scenarios.fetching && !nextProps.scenarios.fetching) {
      this.scenarioLoaded = true;
    }

    if (this.projectLoaded && this.scenarioLoaded) {
      this.hideLoading();
    }

    var error = nextProps.project.error;
    if (error && (error.statusCode === 404 || error.statusCode === 400)) {
      this.hideLoading();
      return hashHistory.push(`/${getLanguage()}/404`);
    }

    if (!this.props.project.fetched && nextProps.project.fetched) {
      // Project just fetched. Validate status;
      if (nextProps.project.data.status === 'pending') {
        return hashHistory.push(`/${getLanguage()}/projects/${this.props.params.projectId}/setup`);
      }
    }

    if (this.props.params.projectId !== nextProps.params.projectId) {
      this.projectLoaded = false;
      this.scenarioLoaded = false;
      this.showLoading();
      this.props._fetchProjectItem(nextProps.params.projectId);
      this.props._fetchProjectScenarios(this.props.params.projectId);
    }

    if (this.props.projectForm.action === 'delete' &&
        this.props.projectForm.processing &&
        !nextProps.projectForm.processing) {
      this.hideLoading();
      if (!nextProps.projectForm.error) {
        return hashHistory.push(`/${getLanguage()}/projects`);
      }
    }
  },

  renderFiles: function () {
    let projectFiles = this.props.project.data.files;
    let projectId = this.props.project.data.id;

    return (

        {projectFiles.map(file => ([
          <dt key={`${file.name}-label`}>{fileTypesMatrix[file.type].display}
,
          <dd key={`${file.name}-desc`}>{fileTypesMatrix[file.type].description}
,
          <dd key={`${file.name}-down`}><a href={`${config.api}/projects/${projectId}/files/${file.id}`} title={t('Download file')} className='psba-download'>{t('Download')}

        ]))}

    );
  },

  renderScenarioCard: function (scenario) {
    let {id, project_id: projectId, name, description} = scenario;

    return (
      <li key={`scenario-${id}`}>
        <article className='scenario scenario--card card' id={`scenario-${id}`}>

                <Link to={`/${getLanguage()}/projects/${projectId}/scenarios/${id}`} title={t('View scenario')} className='link-wrapper'>

{name}

                </Link>

Scenario subtitle

                {description ? (

{description}

                ) : (

{t('No description.')}

                )}

    );
  },

  renderScenariosList: function () {
    let data = this.props.scenarios.data.results;
    return (

        {data.map(scenario => this.renderScenarioCard(scenario))}

          <button className='card__button card__button--add' onClick={() => this.setState({scenarioCreateModal: true})}>{t('New scenario')}</button>

    );
  },

  renderBreadcrumb: function () {
    const items = [
      {
        path: '/projects',
        title: t('Visit projects page'),
        value: t('Projects')
      }
    ];
    return (
      <Breadcrumb items={items}/>
    );
  },

  render: function () {
    let { fetched: fetchedProject, fetching: fetchingProject, error: errorProject, data: dataProject } = this.props.project;
    let { fetched: fetchedScenario, fetching: fetchingScenario, error: errorScenario } = this.props.scenarios;

    let fetched = fetchedProject && fetchedScenario;
    let fetching = fetchingProject && fetchingScenario;
    let error = errorProject || errorScenario;

    if (!fetched && !fetching || !fetched && fetching) {
      return null;
    }

    if (error) {
      return
Error: {prettyPrint(error)}
;
    }

    return (

              {this.renderBreadcrumb()}

{dataProject.name}

            <ProjectHeaderActions
              project={dataProject}
              onAction={this.onProjectAction} />

              {dataProject.description ?
{t('Description')}
 : null}
              {dataProject.description ? (

{dataProject.description}

              ) : null}

{t('Data')}

              {this.renderFiles()}

{t('Scenarios')}

              {this.renderScenariosList()}

        <ProjectFormModal
          editing
          _showGlobalLoading={this.props._showGlobalLoading}
          _hideGlobalLoading={this.props._hideGlobalLoading}
          revealed={this.state.projectFormModal}
          onCloseClick={this.closeModal.bind(null, 'project-form')}
          projectForm={this.props.projectForm}
          projectData={dataProject}
          saveProject={this.props._patchProject}
          resetForm={this.props._resetProjectFrom}
        />

        <ScenarioCreateModal
          _showGlobalLoading={this.props._showGlobalLoading}
          _hideGlobalLoading={this.props._hideGlobalLoading}
          revealed={this.state.scenarioCreateModal}
          onCloseClick={this.closeModal.bind(null, 'new-scenario')}
          scenarioForm={this.props.scenarioForm}
          scenarioList={this.props.scenarios.data.results}
          projectId={this.props.params.projectId}
          saveScenario={this.props._postScenario}
          resetForm={this.props._resetProjectFrom}
        />

    );
  }
});

// /////////////////////////////////////////////////////////////////// //
// Connect functions

function selector (state) {
  return {
    project: state.projectItem,
    scenarios: state.scenarios,
    projectForm: state.projectForm,
    scenarioForm: state.scenarioForm,
  };
}

function dispatcher (dispatch) {
  return {
    _invalidateProjectItem: (...args) => dispatch(invalidateProjectItem(...args)),
    _fetchProjectItem: (...args) => dispatch(fetchProjectItem(...args)),
    _patchProject: (...args) => dispatch(patchProject(...args)),
    _deleteProject: (...args) => dispatch(deleteProject(...args)),
    _showGlobalLoading: (...args) => dispatch(showGlobalLoading(...args)),
    _hideGlobalLoading: (...args) => dispatch(hideGlobalLoading(...args)),
    _fetchProjectScenarios: (...args) => dispatch(fetchProjectScenarios(...args)),
    _resetProjectFrom: (...args) => dispatch(resetProjectFrom(...args)),
    _postScenario: (...args) => dispatch(postScenario(...args))
  };
}

module.exports = connect(selector, dispatcher)(ProjectPageActive);
<commit_msg>Avoid multiple hideLoading triggers<commit_after>'use strict';
import React, { PropTypes as T } from 'react';
import { hashHistory, Link } from 'react-router';
import { connect } from 'react-redux';

import {
  invalidateProjectItem,
  fetchProjectItem,
  patchProject,
  deleteProject,
  showGlobalLoading,
  hideGlobalLoading,
  fetchProjectScenarios,
  resetProjectFrom,
  postScenario
} from '../actions';
import { prettyPrint } from '../utils/utils';
import { t, getLanguage } from '../utils/i18n';
import { fileTypesMatrix } from '../utils/constants';
import config from '../config';

import Breadcrumb from '../components/breadcrumb';
import ProjectFormModal from '../components/project/project-form-modal';
import ProjectHeaderActions from '../components/project/project-header-actions';
import ScenarioCreateModal from '../components/scenario/scenario-create-modal';

var ProjectPageActive = React.createClass({

  propTypes: {
    _invalidateProjectItem: T.func,
    _fetchProjectItem: T.func,
    _patchProject: T.func,
    _deleteProject: T.func,
    _resetProjectFrom: T.func,
    _showGlobalLoading: T.func,
    _hideGlobalLoading: T.func,
    _fetchProjectScenarios: T.func,
    _postScenario: T.func,

    params: T.object,
    project: T.object,
    scenarios: T.object,
    projectForm: T.object,
    scenarioForm: T.object
  },

  getInitialState: function () {
    return {
      projectFormModal: false,
      scenarioCreateModal: false
    };
  },

  // Flag variables to wait for the project and scenario to load.
  projectLoaded: false,
  scenarioLoaded: false,
  loadingVisible: false,

  showLoading: function () {
    this.loadingVisible = true;
    this.props._showGlobalLoading();
  },

  hideLoading: function () {
    this.loadingVisible = false;
    this.props._hideGlobalLoading();
  },

  closeModal: function (what) {
    switch (what) {
      case 'project-form':
        this.setState({projectFormModal: false});
        break;
      case 'new-scenario':
        this.setState({scenarioCreateModal: false});
        break;
    }
  },

  onProjectAction: function (what, event) {
    event.preventDefault();

    switch (what) {
      case 'edit':
        this.setState({projectFormModal: true});
        break;
      case 'delete':
        this.showLoading();
        this.props._deleteProject(this.props.params.projectId);
        break;
      case 'new-scenario':
        this.setState({scenarioCreateModal: true});
        break;
      default:
        throw new Error(`Project action not implemented: ${what}`);
    }
  },

  componentDidMount: function () {
    this.projectLoaded = false;
    this.scenarioLoaded = false;
    this.showLoading();
    this.props._fetchProjectItem(this.props.params.projectId);
    this.props._fetchProjectScenarios(this.props.params.projectId);
  },

  componentWillUnmount: function () {
    this.props._invalidateProjectItem();
  },

  componentWillReceiveProps: function (nextProps) {
    if (this.props.project.fetching && !nextProps.project.fetching) {
      this.projectLoaded = true;
    }
    if (this.props.scenarios.fetching && !nextProps.scenarios.fetching) {
      this.scenarioLoaded = true;
    }

    if (this.projectLoaded && this.scenarioLoaded && this.loadingVisible) {
      this.hideLoading();
    }

    var error = nextProps.project.error;
    if (error && (error.statusCode === 404 || error.statusCode === 400)) {
      this.hideLoading();
      return hashHistory.push(`/${getLanguage()}/404`);
    }

    if (!this.props.project.fetched && nextProps.project.fetched) {
      // Project just fetched. Validate status;
      if (nextProps.project.data.status === 'pending') {
        return hashHistory.push(`/${getLanguage()}/projects/${this.props.params.projectId}/setup`);
      }
    }

    if (this.props.params.projectId !== nextProps.params.projectId) {
      this.projectLoaded = false;
      this.scenarioLoaded = false;
      this.showLoading();
      this.props._fetchProjectItem(nextProps.params.projectId);
      this.props._fetchProjectScenarios(this.props.params.projectId);
    }

    if (this.props.projectForm.action === 'delete' &&
        this.props.projectForm.processing &&
        !nextProps.projectForm.processing) {
      this.hideLoading();
      if (!nextProps.projectForm.error) {
        return hashHistory.push(`/${getLanguage()}/projects`);
      }
    }
  },

  renderFiles: function () {
    let projectFiles = this.props.project.data.files;
    let projectId = this.props.project.data.id;

    return (

        {projectFiles.map(file => ([
          <dt key={`${file.name}-label`}>{fileTypesMatrix[file.type].display}
,
          <dd key={`${file.name}-desc`}>{fileTypesMatrix[file.type].description}
,
          <dd key={`${file.name}-down`}><a href={`${config.api}/projects/${projectId}/files/${file.id}`} title={t('Download file')} className='psba-download'>{t('Download')}

        ]))}

    );
  },

  renderScenarioCard: function (scenario) {
    let {id, project_id: projectId, name, description} = scenario;

    return (
      <li key={`scenario-${id}`}>
        <article className='scenario scenario--card card' id={`scenario-${id}`}>

                <Link to={`/${getLanguage()}/projects/${projectId}/scenarios/${id}`} title={t('View scenario')} className='link-wrapper'>

{name}

                </Link>

Scenario subtitle

                {description ? (

{description}

                ) : (

{t('No description.')}

                )}

    );
  },

  renderScenariosList: function () {
    let data = this.props.scenarios.data.results;
    return (

        {data.map(scenario => this.renderScenarioCard(scenario))}

          <button className='card__button card__button--add' onClick={() => this.setState({scenarioCreateModal: true})}>{t('New scenario')}</button>

    );
  },

  renderBreadcrumb: function () {
    const items = [
      {
        path: '/projects',
        title: t('Visit projects page'),
        value: t('Projects')
      }
    ];
    return (
      <Breadcrumb items={items}/>
    );
  },

  render: function () {
    let { fetched: fetchedProject, fetching: fetchingProject, error: errorProject, data: dataProject } = this.props.project;
    let { fetched: fetchedScenario, fetching: fetchingScenario, error: errorScenario } = this.props.scenarios;

    let fetched = fetchedProject && fetchedScenario;
    let fetching = fetchingProject && fetchingScenario;
    let error = errorProject || errorScenario;

    if (!fetched && !fetching || !fetched && fetching) {
      return null;
    }

    if (error) {
      return
Error: {prettyPrint(error)}
;
    }

    return (

              {this.renderBreadcrumb()}

{dataProject.name}

            <ProjectHeaderActions
              project={dataProject}
              onAction={this.onProjectAction} />

              {dataProject.description ?
{t('Description')}
 : null}
              {dataProject.description ? (

{dataProject.description}

              ) : null}

{t('Data')}

              {this.renderFiles()}

{t('Scenarios')}

              {this.renderScenariosList()}

        <ProjectFormModal
          editing
          _showGlobalLoading={this.props._showGlobalLoading}
          _hideGlobalLoading={this.props._hideGlobalLoading}
          revealed={this.state.projectFormModal}
          onCloseClick={this.closeModal.bind(null, 'project-form')}
          projectForm={this.props.projectForm}
          projectData={dataProject}
          saveProject={this.props._patchProject}
          resetForm={this.props._resetProjectFrom}
        />

        <ScenarioCreateModal
          _showGlobalLoading={this.props._showGlobalLoading}
          _hideGlobalLoading={this.props._hideGlobalLoading}
          revealed={this.state.scenarioCreateModal}
          onCloseClick={this.closeModal.bind(null, 'new-scenario')}
          scenarioForm={this.props.scenarioForm}
          scenarioList={this.props.scenarios.data.results}
          projectId={this.props.params.projectId}
          saveScenario={this.props._postScenario}
          resetForm={this.props._resetProjectFrom}
        />

    );
  }
});

// /////////////////////////////////////////////////////////////////// //
// Connect functions

function selector (state) {
  return {
    project: state.projectItem,
    scenarios: state.scenarios,
    projectForm: state.projectForm,
    scenarioForm: state.scenarioForm,
  };
}

function dispatcher (dispatch) {
  return {
    _invalidateProjectItem: (...args) => dispatch(invalidateProjectItem(...args)),
    _fetchProjectItem: (...args) => dispatch(fetchProjectItem(...args)),
    _patchProject: (...args) => dispatch(patchProject(...args)),
    _deleteProject: (...args) => dispatch(deleteProject(...args)),
    _showGlobalLoading: (...args) => dispatch(showGlobalLoading(...args)),
    _hideGlobalLoading: (...args) => dispatch(hideGlobalLoading(...args)),
    _fetchProjectScenarios: (...args) => dispatch(fetchProjectScenarios(...args)),
    _resetProjectFrom: (...args) => dispatch(resetProjectFrom(...args)),
    _postScenario: (...args) => dispatch(postScenario(...args))
  };
}

module.exports = connect(selector, dispatcher)(ProjectPageActive);
<|endoftext|>


<commit_before>angular.module(PKG.name + '.feature.flows')
  .controller('FlowsDetailRunStatusController', function($state, $scope, MyDataSource) {
    var dataSrc = new MyDataSource($scope),
        basePath = '/apps/' + $state.params.appId + '/flows/' + $state.params.programId;

    var metricsPath = '/metrics/query?metric=system.process.events.processed' +
                          '&context=ns.' +
                          $state.params.namespace +
                          '.app.' + $state.params.appId +
                          '.flow.' + $state.params.programId +
                          '.run.' + $state.params.runId +
                          '.flowlet.';

    $scope.data = {};
    $scope.status = null;
    $scope.duration = null;
    $scope.startTime = null;
    dataSrc.request({
      _cdapNsPath: basePath
    })
      .then(function(res) {
        var nodes = [],
            metrics = {};
        angular.forEach(res.connections, function(conn) {
          if (conn.sourceType === 'STREAM') {
            nodes.push({
              type: conn.sourceType,
              name: conn.sourceName
            });
          }
        });

        angular.forEach(res.flowlets, function (val, key) {
          val.type = 'FLOWLET';
          val.name = key;
          nodes.push(val);
        });

        $scope.data = {
          nodes: nodes,
          edges: res.connections,
          metrics: {}
        };

        // Requesting Metrics data
        angular.forEach(nodes, function (node) {
          dataSrc.request({
            _cdapPath: metricsPath + node.name,
            method: 'POST'
          })
            .then(function (data) {
              $scope.data.metrics[node.name] = data.series[0] ? data.series[0].data[0].value : 0;
            });
        });
      });

    dataSrc.poll({
      _cdapNsPath: basePath + '/runs'
    }, function(res) {
        angular.forEach(res, function(run) {
          if (run.runid === $state.params.runId) {
            $scope.status = run.status;
            $scope.duration = (run.end ? run.end - run.start : (Date.now()/1000) - run.start);
            $scope.startTime = run.start*1000;
          }
        });
      });

  });
<commit_msg>using myHelpers<commit_after>angular.module(PKG.name + '.feature.flows')
  .controller('FlowsDetailRunStatusController', function($state, $scope, MyDataSource, myHelpers) {
    var dataSrc = new MyDataSource($scope),
        basePath = '/apps/' + $state.params.appId + '/flows/' + $state.params.programId;

    var metricsPath = '/metrics/query?metric=system.process.events.processed' +
                          '&context=ns.' +
                          $state.params.namespace +
                          '.app.' + $state.params.appId +
                          '.flow.' + $state.params.programId +
                          '.run.' + $state.params.runId +
                          '.flowlet.';

    $scope.data = {};
    $scope.status = null;
    $scope.duration = null;
    $scope.startTime = null;
    dataSrc.request({
      _cdapNsPath: basePath
    })
      .then(function(res) {
        var nodes = [],
            metrics = {};
        angular.forEach(res.connections, function(conn) {
          if (conn.sourceType === 'STREAM') {
            nodes.push({
              type: conn.sourceType,
              name: conn.sourceName
            });
          }
        });

        angular.forEach(res.flowlets, function (val, key) {
          val.type = 'FLOWLET';
          val.name = key;
          nodes.push(val);
        });

        $scope.data = {
          nodes: nodes,
          edges: res.connections,
          metrics: {}
        };

        // Requesting Metrics data
        angular.forEach(nodes, function (node) {
          dataSrc.request({
            _cdapPath: metricsPath + node.name,
            method: 'POST'
          })
            .then(function (data) {
              // $scope.data.metrics[node.name] = data.series[0] ? data.series[0].data[0].value : 0;
              $scope.data.metrics[node.name] = myHelpers.objectQuery(data, 'series' , 0, 'data', 0, 'value') || 0;
            });
        });
      });

    dataSrc.poll({
      _cdapNsPath: basePath + '/runs'
    }, function(res) {
        angular.forEach(res, function(run) {
          if (run.runid === $state.params.runId) {
            $scope.status = run.status;
            $scope.duration = (run.end ? run.end - run.start : (Date.now()/1000) - run.start);
            $scope.startTime = run.start*1000;
          }
        });
      });

  });
<|endoftext|>


<commit_before>'use strict'

import React, { Component } from 'react'
import ReactCSS from 'reactcss'

import ComposerFormSubmit from './ComposerFormSubmit'

import colors from '../../assets/styles/variables/colors'

class ComposerAliasSuccess extends Component {
  classes() {
    return {
      'default': {
        title: {
          textAlign: 'center',
          fontSize: '24px',
          width: '80%',
          margin: '0 auto',
          marginBottom: '20px',
        },
        body: {
          width: '80%',
          textAlign: 'center',
          margin: '0px auto 20px',
        },
        iframe: {
          border: 'none',
          margin: '0 auto',
          display: 'block',
          marginTop: '35px',
          marginBottom: '35px',
        },
        actions: {
          marginTop: '-10px',
          height: '40px',
          padding: '20px',
        },
        confirm: {
          color: '#fff',
          padding: '10px 30px',
          borderRadius: '5px',
          backgroundColor: colors.primary,
          textDecoration: 'none',
          cursor: 'pointer',
          textAlign: 'center',
          display: 'block',
          transition: '200ms ease-in-out',
        },
      },
      'hover': {
        input: {
          border: 'solid 1px red',
        },
        confirm: {
          backgroundColor: '#BF1B23',
        },
      },
    }
  }

  render() {
    return (

Your keys are generating.

In the meantime, support easy to use encryption 😊

          <ComposerFormSubmit
            onClick={ this.props.handleCancel }
            value="Enter Felony"
          />

    )
  }
}

export default ReactCSS.Hover(ReactCSS(ComposerAliasSuccess))
<commit_msg>Support for felony instead of for bootstrap<commit_after>'use strict'

import React, { Component } from 'react'
import ReactCSS from 'reactcss'

import ComposerFormSubmit from './ComposerFormSubmit'

import colors from '../../assets/styles/variables/colors'

class ComposerAliasSuccess extends Component {
  classes() {
    return {
      'default': {
        title: {
          textAlign: 'center',
          fontSize: '24px',
          width: '80%',
          margin: '0 auto',
          marginBottom: '20px',
        },
        body: {
          width: '80%',
          textAlign: 'center',
          margin: '0px auto 20px',
        },
        iframe: {
          border: 'none',
          margin: '0 auto',
          display: 'block',
          marginTop: '35px',
          marginBottom: '35px',
        },
        actions: {
          marginTop: '-10px',
          height: '40px',
          padding: '20px',
        },
        confirm: {
          color: '#fff',
          padding: '10px 30px',
          borderRadius: '5px',
          backgroundColor: colors.primary,
          textDecoration: 'none',
          cursor: 'pointer',
          textAlign: 'center',
          display: 'block',
          transition: '200ms ease-in-out',
        },
      },
      'hover': {
        input: {
          border: 'solid 1px red',
        },
        confirm: {
          backgroundColor: '#BF1B23',
        },
      },
    }
  }

  render() {
    return (

Your keys are generating.

In the meantime, support easy to use encryption 😊

          <ComposerFormSubmit
            onClick={ this.props.handleCancel }
            value="Enter Felony"
          />

    )
  }
}

export default ReactCSS.Hover(ReactCSS(ComposerAliasSuccess))
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import TwemojiComp from 'react-twemoji';
import Twemoji from 'twemoji';
import EmojiPicker from '../emoji_picker/emoji_picker';

function replaceAll(string, search, replacement) {
  return string.replace(new RegExp(search, 'g'), replacement);
}

class ContentEditable extends Component {
  constructor(props) {
    super(props);
    this.state = {
      pickerActive: false,
      content: '',
      previewContent: '',
      pickerStyle: {
        bottom: '5px',
        right: '0px',
      },
    };
  }
  shouldComponentUpdate() {
    return true;
  }
  onChange(value, caretOffset = 0) {
    this.setState({ content: value });
    let content = value;
    let caretPos = 0;
    if (this.textarea) {
      caretPos = this.textarea.selectionStart;
    }
    content = ContentEditable.moveCaret(content, caretPos + caretOffset);
    content = content.replace(/(?:\r\n|\r|\n)/g, '
');
    content = content.replace(/(?:\r\n|\r|\n)/g, '
');
    this.setState({ previewContent: content });
  }
  static moveCaret(content, caretPos) {
    return `${content.slice(0, caretPos)}<span id="cursor">|</span>${content.slice(caretPos)}`;
  }
  getContent() {
    let content = this.state.content;
    let caretPos = 0;
    if (this.textarea) {
      caretPos = this.textarea.selectionStart;
    }
    content = ContentEditable.moveCaret(content, caretPos);
    content = content.replace(/(?:\r\n|\r|\n)/g, '
');
    return Twemoji.parse(content);
  }
  ontextareaClick() {
    let content = this.state.content;
    let caretPos = 0;
    if (this.textarea) {
      caretPos = this.textarea.selectionStart;
    }
    content = ContentEditable.moveCaret(content, caretPos);
    this.setState({ previewContent: content });
  }
  keyDown(e) {
    console.log(e.keyCode);
    if (e.keyCode == 37 || e.keyCode == 39) {
      this.ontextareaClick();
    }
  }
  toggleEmojiPicker() {
    const emojiTrigger = this.node;
    const triggerStyles = getComputedStyle(emojiTrigger);
    const bottom = `${parseInt(triggerStyles.bottom, 10) + emojiTrigger.clientHeight + 10}px`;
    this.setState({
      pickerActive: !this.state.pickerActive,
      pickerStyle: {
        bottom,
        right: '0px',
      },
    });
  }
  addEmoji(emoji) {
    const content = this.state.content + emoji;
    this.onChange(content, emoji.length);
  }
  render() {
    const { pickerActive } = this.state;
    return (
      <div
        className={`content_editable ${this.props.className}`}
        id={this.props.id}
        ref={(node) => { this.node = node; }}
      >
        <textarea
          className="textarea"
          onChange={(e) => { this.onChange(e.target.value); }}
          value={this.state.content}
          ref={(node) => { this.textarea = node; }}
          onClick={e => this.ontextareaClick(e)}
          onKeyUp={e => this.keyDown(e)}
        />

 { this.previewNode = node; }}
          dangerouslySetInnerHTML={{ __html: Twemoji.parse(this.state.previewContent) }}
        />
        <TwemojiComp
          className="emoji_trigger"
          onClick={() => this.toggleEmojiPicker()}
        >
          🙂
        </TwemojiComp>
        { pickerActive ? <EmojiPicker
          style={this.state.pickerStyle}
          onPick={emoji => this.addEmoji(emoji)}
        /> : null }

    );
  }
}

ContentEditable.propTypes = {
  className: PropTypes.string, // eslint-disable-line
  id: PropTypes.string, // eslint-disable-line
};

export default ContentEditable;
<commit_msg>: syntax bois<commit_after>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import TwemojiComp from 'react-twemoji';
import Twemoji from 'twemoji';
import EmojiPicker from '../emoji_picker/emoji_picker';

function replaceAll(string, search, replacement) {
  return string.replace(new RegExp(search, 'g'), replacement);
}

class ContentEditable extends Component {
  constructor(props) {
    super(props);
    this.state = {
      pickerActive: false,
      content: '',
      previewContent: '',
      pickerStyle: {
        bottom: '5px',
        right: '0px',
      },
    };
  }
  shouldComponentUpdate() {
    return true;
  }
  onChange(value, caretOffset = 0) {
    this.setState({ content: value });
    let content = value;
    let caretPos = 0;
    if (this.textarea) {
      caretPos = this.textarea.selectionStart;
    }
    content = ContentEditable.moveCaret(content, caretPos + caretOffset);
    content = content.replace(/(?:\r\n|\r|\n)/g, '
');
    content = content.replace(/(?:\r\n|\r|\n)/g, '
');
    this.setState({ previewContent: content });
  }
  static moveCaret(content, caretPos) {
    return `${content.slice(0, caretPos)}<span id="cursor">|</span>${content.slice(caretPos)}`;
  }
  getContent() {
    let content = this.state.content;
    let caretPos = 0;
    if (this.textarea) {
      caretPos = this.textarea.selectionStart;
    }
    content = ContentEditable.moveCaret(content, caretPos);
    content = content.replace(/(?:\r\n|\r|\n)/g, '
');
    return Twemoji.parse(content);
  }
  ontextareaClick() {
    let content = this.state.content;
    let caretPos = 0;
    if (this.textarea) {
      caretPos = this.textarea.selectionStart;
    }
    content = ContentEditable.moveCaret(content, caretPos);
    this.setState({ previewContent: content });
  }
  keyDown(e) {
    let caretPos = 0;
    if (this.textarea) {
      caretPos = this.textarea.selectionStart;
    }

    const preText = this.textarea.value.substring(0, caretPos).split(' ').pop();
    if (preText.indexOf(':') > -1) {
      const word = preText.split(':').pop();
      console.log(word); // this is the emoji
    }

    if (e.keyCode === 37 || e.keyCode === 39) {
      this.ontextareaClick();
    }
  }
  toggleEmojiPicker() {
    const emojiTrigger = this.node;
    const triggerStyles = getComputedStyle(emojiTrigger);
    const bottom = `${parseInt(triggerStyles.bottom, 10) + emojiTrigger.clientHeight + 10}px`;
    this.setState({
      pickerActive: !this.state.pickerActive,
      pickerStyle: {
        bottom,
        right: '0px',
      },
    });
  }
  addEmoji(emoji) {
    const content = this.state.content + emoji;
    this.onChange(content, emoji.length);
  }
  render() {
    const { pickerActive } = this.state;
    return (
      <div
        className={`content_editable ${this.props.className}`}
        id={this.props.id}
        ref={(node) => { this.node = node; }}
      >
        <textarea
          className="textarea"
          onChange={(e) => { this.onChange(e.target.value); }}
          value={this.state.content}
          ref={(node) => { this.textarea = node; }}
          onClick={e => this.ontextareaClick(e)}
          onKeyUp={e => this.keyDown(e)}
        />

 { this.previewNode = node; }}
          dangerouslySetInnerHTML={{ __html: Twemoji.parse(this.state.previewContent) }}
        />
        <TwemojiComp
          className="emoji_trigger"
          onClick={() => this.toggleEmojiPicker()}
        >
          🙂
        </TwemojiComp>
        { pickerActive ? <EmojiPicker
          style={this.state.pickerStyle}
          onPick={emoji => this.addEmoji(emoji)}
        /> : null }

    );
  }
}

ContentEditable.propTypes = {
  className: PropTypes.string, // eslint-disable-line
  id: PropTypes.string, // eslint-disable-line
};

export default ContentEditable;
<|endoftext|>


<commit_before>var React = require('react');
var classNames = require('classnames');

var AvatarItem = React.createClass({
  propTypes: {
    title: React.PropTypes.string.isRequired,
    image: React.PropTypes.string,
    placeholder: React.PropTypes.string,
    size: React.PropTypes.string
  },

  render: function() {
    var title = this.props.title;
    var image = this.props.image;
    var size = this.props.size;
    var placeholderClassName = "avatar__placeholder avatar__placeholder--" + this.props.placeholder;
    var avatarClassName = classNames('avatar', {
      'avatar--small': size == 'small',
      'avatar--tiny': size == 'tiny'
    });

    var placeholder = {title[0]}

    var avatar;
    if (image) {
      avatar =
    }

    return(

        {avatar}
        {placeholder}

    );
  }
});

module.exports = AvatarItem;
<commit_msg>fix(web): add class to avatar image;<commit_after>var React = require('react');
var classNames = require('classnames');

var AvatarItem = React.createClass({
  propTypes: {
    title: React.PropTypes.string.isRequired,
    image: React.PropTypes.string,
    placeholder: React.PropTypes.string,
    size: React.PropTypes.string
  },

  render: function() {
    var title = this.props.title;
    var image = this.props.image;
    var size = this.props.size;
    var placeholderClassName = "avatar__placeholder avatar__placeholder--" + this.props.placeholder;
    var avatarClassName = classNames('avatar', {
      'avatar--small': size == 'small',
      'avatar--tiny': size == 'tiny'
    });

    var placeholder = {title[0]}

    var avatar;
    if (image) {
      avatar =
    }

    return(

        {avatar}
        {placeholder}

    );
  }
});

module.exports = AvatarItem;
<|endoftext|>


<commit_before>'use strict';

/**
 * Module dependencies.
 */
var mongoose = require('mongoose');
var errorHandler = require('./errors.server.controller');
var Vocablist = mongoose.model('Vocablist');
var _ = require('lodash');
var Vocab = mongoose.model('Vocab');
var rsvp = require('rsvp');

function findVocabPromise(vocab) {
  return new rsvp.Promise(function(resolve, error) {
    Vocab.findById(vocab._id,
      function(err, doc) {
        if (err) {
          error(err);
        } else if (!doc) {
          error(new Error('Failed to load Vocab ' + vocab._id));
        } else {
          _.extend(doc, vocab);
          resolve(doc);
        }
      }
    );
  });
}

function makeFindVocabPromises(vocabs) {
  var promises = [];
  for (var i = 0; i < vocabs.length; i++) {
    promises.push(findVocabPromise(vocabs[i]));
  }
  return rsvp.all(promises);
}

function makeSaveVocabPromise(vocab) {
  return new rsvp.Promise(function(resolve, error) {
    vocab.save(function(err) {
      if (err) {
        error(err);
      } else {
        resolve();
      }
    });
  });
}

function makeSaveVocabPromises(vocabs) {
  var promises = [];
  for (var i = 0; i < vocabs.length; i++) {
    promises.push(makeSaveVocabPromise(vocabs[i]));
  }
  return rsvp.all(promises);
}

function saveVocablistPromise(vocablist) {
  return new rsvp.Promise(function(resolve, error) {
    vocablist.save(function(err) {
      if (err) {
        error(err);
      } else {
        resolve(vocablist);
      }
    });
  });
}

function populateVocablist(vocablist) {
  return new rsvp.Promise(function(resolve, error) {
    vocablist.populate('vocab', function(err) {
      if (err) {
        error(err);
      } else {
        resolve(vocablist);
      }
    });
  });
}

/**
 * Create a Vocablist
 */
exports.create = function(req, res) {
  var vocabs = req.body.vocab;
  Vocab.create(vocabs).
    then(function(vocabDocs) {
      console.log('Successfully created vocabs');
      var vocablist = req.body;
      vocablist.vocab = vocabDocs;
      return Vocablist.create(vocablist);
    }).
    then(function(vocablist) {
      console.log('Successfully saved vocablist');
      res.jsonp(vocablist);
      return;
    }).
    catch(function(err) {
      return res.status(400).send({
        message: errorHandler.getErrorMessage(err)
      });
    });
};

/**
 * Show the current Vocablist
 */
exports.read = function(req, res) {
  req.vocablist.populate('vocab', function(err) {
    if (err) {
      return res.status(400).send(new Error('Failed to load Vocablist ' + req.vocablist._id));
    } else {
      res.jsonp(req.vocablist);
    }
  });
};

/**
 * Update a Vocablist
 */
exports.update = function(req, res) {
  var vocablist = req.vocablist;
  vocablist = _.extend(vocablist , req.body);
  makeFindVocabPromises(req.body.vocab).then(makeSaveVocabPromises).
    then(function() {
      return saveVocablistPromise(vocablist);
    }).
    then(populateVocablist).
    then(function(vocablist) {
      res.jsonp(vocablist);
    }).
    catch(
      function(err) {
        return res.status(400).send({
          message: errorHandler.getErrorMessage(err)
        });
      }
    );
};

function deleteVocabs(vocablist) {
  var ids = [];
  for (var i = 0; i < vocablist.vocab.length; i++) {
    ids.push(vocablist.vocab[i]);
  }
  return Vocab.remove({_id: {$in: ids}});
}

/**
 * Delete an Vocablist
 */
exports.delete = function(req, res) {
  var vocablist = req.vocablist;
  deleteVocabs(vocablist).then(function() {
    return vocablist.remove();
  }).then(function() {
    res.jsonp(vocablist);
  }).catch(function(err) {
    return res.status(400).send({
      message: errorHandler.getErrorMessage(err)
    });
  });
};

/**
 * List of Vocablists
 */
exports.list = function(req, res) {
  Vocablist.find().sort('-created').populate('vocab').exec(function(err, vocablists) {
    if (err) {
      return res.status(400).send({
        message: errorHandler.getErrorMessage(err)
      });
    } else {
      res.jsonp(vocablists);
    }
  });
};

/**
 * Vocablist middleware
 */
exports.vocablistByID = function(req, res, next, id) {
  Vocablist.findById(id).exec(function(err, vocablist) {
    if (err) {
      return next(err);
    }
    if (!vocablist) {
      return next(new Error('Failed to load Vocablist ' + id));
    }
    req.vocablist = vocablist;
    next();
  });
};

/**
 * Vocablist authorization middleware
 */
exports.hasAuthorization = function(req, res, next) {
  if (req.vocablist.user.id !== req.user.id) {
    return res.status(403).send('User is not authorized');
  }
  next();
};
<commit_msg>Adds parameters to restrict retrieving of vocablists<commit_after>'use strict';

/**
 * Module dependencies.
 */
var mongoose = require('mongoose');
var errorHandler = require('./errors.server.controller');
var Vocablist = mongoose.model('Vocablist');
var _ = require('lodash');
var Vocab = mongoose.model('Vocab');
var rsvp = require('rsvp');

function findVocabPromise(vocab) {
  return new rsvp.Promise(function(resolve, error) {
    Vocab.findById(vocab._id,
      function(err, doc) {
        if (err) {
          error(err);
        } else if (!doc) {
          error(new Error('Failed to load Vocab ' + vocab._id));
        } else {
          _.extend(doc, vocab);
          resolve(doc);
        }
      }
    );
  });
}

function makeFindVocabPromises(vocabs) {
  var promises = [];
  for (var i = 0; i < vocabs.length; i++) {
    promises.push(findVocabPromise(vocabs[i]));
  }
  return rsvp.all(promises);
}

function makeSaveVocabPromise(vocab) {
  return new rsvp.Promise(function(resolve, error) {
    vocab.save(function(err) {
      if (err) {
        error(err);
      } else {
        resolve();
      }
    });
  });
}

function makeSaveVocabPromises(vocabs) {
  var promises = [];
  for (var i = 0; i < vocabs.length; i++) {
    promises.push(makeSaveVocabPromise(vocabs[i]));
  }
  return rsvp.all(promises);
}

function saveVocablistPromise(vocablist) {
  return new rsvp.Promise(function(resolve, error) {
    vocablist.save(function(err) {
      if (err) {
        error(err);
      } else {
        resolve(vocablist);
      }
    });
  });
}

function populateVocablist(vocablist) {
  return new rsvp.Promise(function(resolve, error) {
    vocablist.populate('vocab', function(err) {
      if (err) {
        error(err);
      } else {
        resolve(vocablist);
      }
    });
  });
}

/**
 * Create a Vocablist
 */
exports.create = function(req, res) {
  var vocabs = req.body.vocab;
  Vocab.create(vocabs).
    then(function(vocabDocs) {
      console.log('Successfully created vocabs');
      var vocablist = req.body;
      vocablist.vocab = vocabDocs;
      return Vocablist.create(vocablist);
    }).
    then(function(vocablist) {
      console.log('Successfully saved vocablist');
      res.jsonp(vocablist);
      return;
    }).
    catch(function(err) {
      return res.status(400).send({
        message: errorHandler.getErrorMessage(err)
      });
    });
};

/**
 * Show the current Vocablist
 */
exports.read = function(req, res) {
  req.vocablist.populate('vocab', function(err) {
    if (err) {
      return res.status(400).send(new Error('Failed to load Vocablist ' + req.vocablist._id));
    } else {
      res.jsonp(req.vocablist);
    }
  });
};

/**
 * Update a Vocablist
 */
exports.update = function(req, res) {
  var vocablist = req.vocablist;
  vocablist = _.extend(vocablist , req.body);
  makeFindVocabPromises(req.body.vocab).then(makeSaveVocabPromises).
    then(function() {
      return saveVocablistPromise(vocablist);
    }).
    then(populateVocablist).
    then(function(vocablist) {
      res.jsonp(vocablist);
    }).
    catch(
      function(err) {
        return res.status(400).send({
          message: errorHandler.getErrorMessage(err)
        });
      }
    );
};

function deleteVocabs(vocablist) {
  var ids = [];
  for (var i = 0; i < vocablist.vocab.length; i++) {
    ids.push(vocablist.vocab[i]);
  }
  return Vocab.remove({_id: {$in: ids}});
}

/**
 * Delete an Vocablist
 */
exports.delete = function(req, res) {
  var vocablist = req.vocablist;
  deleteVocabs(vocablist).then(function() {
    return vocablist.remove();
  }).then(function() {
    res.jsonp(vocablist);
  }).catch(function(err) {
    return res.status(400).send({
      message: errorHandler.getErrorMessage(err)
    });
  });
};

/**
 * List of Vocablists
 */
exports.list = function(req, res) {
  var query = req.query.userId ? {user: req.query.userId} : {};
  Vocablist.find(query).sort('-created').populate('vocab').exec(function(err, vocablists) {
    if (err) {
      return res.status(400).send({
        message: errorHandler.getErrorMessage(err)
      });
    } else {
      res.jsonp(vocablists);
    }
  });
};

/**
 * Vocablist middleware
 */
exports.vocablistByID = function(req, res, next, id) {
  Vocablist.findById(id).exec(function(err, vocablist) {
    if (err) {
      return next(err);
    }
    if (!vocablist) {
      return next(new Error('Failed to load Vocablist ' + id));
    }
    req.vocablist = vocablist;
    next();
  });
};

/**
 * Vocablist authorization middleware
 */
exports.hasAuthorization = function(req, res, next) {
  if (req.vocablist.user.id !== req.user.id) {
    return res.status(403).send('User is not authorized');
  }
  next();
};
<|endoftext|>


<commit_before>import { expect } from 'chai';
import React from 'react';
import ControlLabel from 'react-bootstrap/lib/ControlLabel';
import FormGroup from 'react-bootstrap/lib/FormGroup';
import Select from 'react-select';
import simple from 'simple-mock';

import { shallowWithIntl } from 'utils/testUtils';
import SelectControl from './SelectControl';

const defaults = {
  id: 'some-id',
  name: 'some-name',
  isLoading: false,
  label: 'some-label',
  onChange: () => null,
  options: [
    { value: 'filter-1', label: 'Label 1' },
    { value: 'filter-2', label: 'Label 2' },
  ],
  value: 'filter-1',
};
function getWrapper(props) {
  return shallowWithIntl(<SelectControl {...defaults} {...props} />);
}

describe('pages/search/controls/SelectControl', () => {
  afterEach(() => {
    simple.restore();
  });

  it('renders a div.app-SelectControl', () => {
    const wrapper = getWrapper({});
    expect(wrapper.is('div.app-SelectControl')).to.be.true;
  });

  it('renders a FormGroup with correct props', () => {
    const formGroup = getWrapper({}).find(FormGroup);
    expect(formGroup).to.have.length(1);
    expect(formGroup.prop('controlId')).to.equal(defaults.id);
  });

  it('renders a ControlLabel', () => {
    const controlLabel = getWrapper({}).find(ControlLabel);
    expect(controlLabel).to.have.length(1);
  });

  it('hide Select when isLoading=true', () => {
    const select = getWrapper({ isLoading: true }).find(Select);

    expect(select).to.have.length(0);
  });

  it('disable Select when isDisable was true', () => {
    const select = getWrapper({ isDisable: true }).find(Select);

    expect(select.prop('isDisable')).to.be.true;
  });

  it('renders a Select with correct props', () => {
    const select = getWrapper({}).find(Select);
    expect(select).to.have.length(1);
    expect(select.prop('isClearable')).to.be.true;
    expect(select.prop('id')).to.equal(defaults.id);
    expect(select.prop('name')).to.equal(defaults.name);
    expect(select.prop('onChange')).to.be.a('function');
    expect(select.prop('placeholder')).to.equal('common.select');
    expect(select.prop('isSearchable')).to.be.true;
    expect(select.prop('value')).to.equal(defaults.options[0]);
  });

  it('Select onChange calls prop onChange', () => {
    const onChange = simple.mock();
    const select = getWrapper({ onChange }).find(Select);
    expect(select).to.have.length(1);
    select.prop('onChange')(defaults.options[1], {});
    expect(onChange.callCount).to.equal(1);
    expect(onChange.lastCall.args[0]).to.deep.equal(defaults.options[1]);
  });

  it('Select onChange calls prop onChange when clear selected field', () => {
    const onChange = simple.mock();
    const multiSelect = getWrapper({ onChange, isMulti: true }).find(Select);
    expect(multiSelect).to.have.length(1);
    multiSelect.prop('onChange')(defaults.options, { action: 'clear' });
    expect(onChange.callCount).to.equal(1);
    expect(onChange.lastCall.args[0]).to.equal([]);
  });

  it('call props onChange with multi select if isMulti is true', () => {
    const onChange = simple.mock();
    const select = getWrapper({ onChange, isMulti: true }).find(Select);

    expect(select).to.have.length(1);
    select.prop('onChange')(defaults.options, {});
    expect(onChange.callCount).to.equal(1);
    expect(onChange.lastCall.args[0]).to.deep.equal(defaults.options);
  });

  describe('getValue', () => {
    it('fill selected option when default value is passed in', () => {
      const wrapper = getWrapper({});
      const selectedOption = wrapper.instance().getValue(defaults.options[0].value, defaults.options);
      expect(selectedOption).to.deep.equal(defaults.options[0]);
    });

    it('return underfined if value is not exist in any options', () => {
      const wrapper = getWrapper({});
      const selectedOption = wrapper.instance().getValue('foo', defaults.options);
      expect(selectedOption).to.be.undefined;
    });

    it('return array of options if value is array', () => {
      const wrapper = getWrapper({});
      const selectedOption = wrapper.instance().getValue(['filter-1', 'filter-2'], defaults.options);
      expect(selectedOption).to.deep.equal(defaults.options);
    });
  });
});
<commit_msg>fix lint typo<commit_after>import { expect } from 'chai';
import React from 'react';
import ControlLabel from 'react-bootstrap/lib/ControlLabel';
import FormGroup from 'react-bootstrap/lib/FormGroup';
import Select from 'react-select';
import simple from 'simple-mock';

import { shallowWithIntl } from 'utils/testUtils';
import SelectControl from './SelectControl';

const defaults = {
  id: 'some-id',
  name: 'some-name',
  isLoading: false,
  label: 'some-label',
  onChange: () => null,
  options: [
    { value: 'filter-1', label: 'Label 1' },
    { value: 'filter-2', label: 'Label 2' },
  ],
  value: 'filter-1',
};
function getWrapper(props) {
  return shallowWithIntl(<SelectControl {...defaults} {...props} />);
}

describe('pages/search/controls/SelectControl', () => {
  afterEach(() => {
    simple.restore();
  });

  it('renders a div.app-SelectControl', () => {
    const wrapper = getWrapper({});
    expect(wrapper.is('div.app-SelectControl')).to.be.true;
  });

  it('renders a FormGroup with correct props', () => {
    const formGroup = getWrapper({}).find(FormGroup);
    expect(formGroup).to.have.length(1);
    expect(formGroup.prop('controlId')).to.equal(defaults.id);
  });

  it('renders a ControlLabel', () => {
    const controlLabel = getWrapper({}).find(ControlLabel);
    expect(controlLabel).to.have.length(1);
  });

  it('hide Select when isLoading=true', () => {
    const select = getWrapper({ isLoading: true }).find(Select);

    expect(select).to.have.length(0);
  });

  it('disable Select when isDisable was true', () => {
    const select = getWrapper({ isDisable: true }).find(Select);

    expect(select.prop('isDisable')).to.be.true;
  });

  it('renders a Select with correct props', () => {
    const select = getWrapper({}).find(Select);
    expect(select).to.have.length(1);
    expect(select.prop('isClearable')).to.be.true;
    expect(select.prop('id')).to.equal(defaults.id);
    expect(select.prop('name')).to.equal(defaults.name);
    expect(select.prop('onChange')).to.be.a('function');
    expect(select.prop('placeholder')).to.equal('common.select');
    expect(select.prop('isSearchable')).to.be.true;
    expect(select.prop('value')).to.equal(defaults.options[0]);
  });

  it('Select onChange calls prop onChange', () => {
    const onChange = simple.mock();
    const select = getWrapper({ onChange }).find(Select);
    expect(select).to.have.length(1);
    select.prop('onChange')(defaults.options[1], {});
    expect(onChange.callCount).to.equal(1);
    expect(onChange.lastCall.args[0]).to.deep.equal(defaults.options[1]);
  });

  it('Select onChange calls prop onChange when clear selected field', () => {
    const onChange = simple.mock();
    const multiSelect = getWrapper({ onChange, isMulti: true }).find(Select);
    expect(multiSelect).to.have.length(1);
    multiSelect.prop('onChange')(defaults.options, { action: 'clear' });
    expect(onChange.callCount).to.equal(1);
    expect(onChange.lastCall.args[0]).to.equal([]);
  });

  it('call props onChange with multi select if isMulti is true', () => {
    const onChange = simple.mock();
    const select = getWrapper({ onChange, isMulti: true }).find(Select);

    expect(select).to.have.length(1);
    select.prop('onChange')(defaults.options, {});
    expect(onChange.callCount).to.equal(1);
    expect(onChange.lastCall.args[0]).to.deep.equal(defaults.options);
  });

  describe('getValue', () => {
    it('fill selected option when default value is passed in', () => {
      const wrapper = getWrapper({});
      const selectedOption = wrapper.instance().getValue(
        defaults.options[0].value, defaults.options);
      expect(selectedOption).to.deep.equal(defaults.options[0]);
    });

    it('return underfined if value is not exist in any options', () => {
      const wrapper = getWrapper({});
      const selectedOption = wrapper.instance().getValue('foo', defaults.options);
      expect(selectedOption).to.be.undefined;
    });

    it('return array of options if value is array', () => {
      const wrapper = getWrapper({});
      const selectedOption = wrapper.instance().getValue(['filter-1', 'filter-2'], defaults.options);
      expect(selectedOption).to.deep.equal(defaults.options);
    });
  });
});
<|endoftext|>


<commit_before>import { expect } from 'chai';
import React from 'react';
import ControlLabel from 'react-bootstrap/lib/ControlLabel';
import FormGroup from 'react-bootstrap/lib/FormGroup';
import Select from 'react-select';
import simple from 'simple-mock';

import { shallowWithIntl } from 'utils/testUtils';
import SelectControl from './SelectControl';

const defaults = {
  id: 'some-id',
  name: 'some-name',
  isLoading: false,
  label: 'some-label',
  onChange: () => null,
  options: [
    { value: 'filter-1', label: 'Label 1' },
    { value: 'filter-2', label: 'Label 2' },
  ],
  value: 'filter-1',
};
function getWrapper(props) {
  return shallowWithIntl(<SelectControl {...defaults} {...props} />);
}

describe('pages/search/controls/SelectControl', () => {
  afterEach(() => {
    simple.restore();
  });

  it('renders a div.app-SelectControl', () => {
    const wrapper = getWrapper({});
    expect(wrapper.is('div.app-SelectControl')).to.be.true;
  });

  it('renders a FormGroup with correct props', () => {
    const formGroup = getWrapper({}).find(FormGroup);
    expect(formGroup).to.have.length(1);
    expect(formGroup.prop('controlId')).to.equal(defaults.id);
  });

  it('renders a ControlLabel', () => {
    const controlLabel = getWrapper({}).find(ControlLabel);
    expect(controlLabel).to.have.length(1);
  });

  it('hide Select when isLoading=true', () => {
    const select = getWrapper({ isLoading: true }).find(Select);

    expect(select).to.have.length(0);
  });

  it('disable Select when isDisable was true', () => {
    const select = getWrapper({ isDisable: true }).find(Select);

    expect(select.prop('isDisable')).to.be.true;
  });

  it('renders a Select with correct props', () => {
    const select = getWrapper({}).find(Select);
    expect(select).to.have.length(1);
    expect(select.prop('isClearable')).to.be.true;
    expect(select.prop('id')).to.equal(defaults.id);
    expect(select.prop('name')).to.equal(defaults.name);
    expect(select.prop('onChange')).to.be.a('function');
    expect(select.prop('placeholder')).to.equal('common.select');
    expect(select.prop('isSearchable')).to.be.true;
    expect(select.prop('value')).to.equal(defaults.options[0]);
  });

  it('Select onChange calls prop onChange', () => {
    const onChange = simple.mock();
    const select = getWrapper({ onChange }).find(Select);
    expect(select).to.have.length(1);
    select.prop('onChange')(defaults.options[1], {});
    expect(onChange.callCount).to.equal(1);
    expect(onChange.lastCall.args[0]).to.deep.equal(defaults.options[1]);
  });

  it('Select onChange calls prop onChange when clear selected field', () => {
    const onChange = simple.mock();
    const multiSelect = getWrapper({ onChange, isMulti: true }).find(Select);
    expect(multiSelect).to.have.length(1);
    multiSelect.prop('onChange')(defaults.options, { action: 'clear' });
    expect(onChange.callCount).to.equal(1);
    expect(onChange.lastCall.args[0]).to.equal([]);
  });

  it('call props onChange with multi select if isMulti is true', () => {
    const onChange = simple.mock();
    const select = getWrapper({ onChange, isMulti: true }).find(Select);

    expect(select).to.have.length(1);
    select.prop('onChange')(defaults.options, {});
    expect(onChange.callCount).to.equal(1);
    expect(onChange.lastCall.args[0]).to.deep.equal(defaults.options);
  });

  describe('getValue', () => {
    it('fill selected option when default value is passed in', () => {
      const wrapper = getWrapper({});
      const selectedOption = wrapper.instance().getValue(
        defaults.options[0].value, defaults.options);
      expect(selectedOption).to.deep.equal(defaults.options[0]);
    });

    it('return underfined if value is not exist in any options', () => {
      const wrapper = getWrapper({});
      const selectedOption = wrapper.instance().getValue('foo', defaults.options);
      expect(selectedOption).to.be.undefined;
    });

    it('return array of options if value is array', () => {
      const wrapper = getWrapper({});
      const selectedOption = wrapper.instance().getValue(['filter-1', 'filter-2'], defaults.options);
      expect(selectedOption).to.deep.equal(defaults.options);
    });
  });
});
<commit_msg>add more test, add deep equal check<commit_after>import { expect } from 'chai';
import React from 'react';
import ControlLabel from 'react-bootstrap/lib/ControlLabel';
import FormGroup from 'react-bootstrap/lib/FormGroup';
import Select from 'react-select';
import simple from 'simple-mock';

import { shallowWithIntl } from 'utils/testUtils';
import SelectControl from './SelectControl';

const defaults = {
  id: 'some-id',
  name: 'some-name',
  isLoading: false,
  label: 'some-label',
  onChange: () => null,
  options: [
    { value: 'filter-1', label: 'Label 1' },
    { value: 'filter-2', label: 'Label 2' },
  ],
  value: 'filter-1',
};
function getWrapper(props) {
  return shallowWithIntl(<SelectControl {...defaults} {...props} />);
}

describe('pages/search/controls/SelectControl', () => {
  afterEach(() => {
    simple.restore();
  });

  it('renders a div.app-SelectControl', () => {
    const wrapper = getWrapper({});
    expect(wrapper.is('div.app-SelectControl')).to.be.true;
  });

  it('renders a FormGroup with correct props', () => {
    const formGroup = getWrapper({}).find(FormGroup);
    expect(formGroup).to.have.length(1);
    expect(formGroup.prop('controlId')).to.equal(defaults.id);
  });

  it('renders a ControlLabel', () => {
    const controlLabel = getWrapper({}).find(ControlLabel);
    expect(controlLabel).to.have.length(1);
  });

  it('hide Select when isLoading=true', () => {
    const select = getWrapper({ isLoading: true }).find(Select);

    expect(select).to.have.length(0);
  });

  it('disable Select when isDisable was true', () => {
    const select = getWrapper({ isDisable: true }).find(Select);

    expect(select.prop('isDisable')).to.be.true;
  });

  it('renders a Select with correct props', () => {
    const select = getWrapper({}).find(Select);
    expect(select).to.have.length(1);
    expect(select.prop('isClearable')).to.be.true;
    expect(select.prop('id')).to.equal(defaults.id);
    expect(select.prop('name')).to.equal(defaults.name);
    expect(select.prop('onChange')).to.be.a('function');
    expect(select.prop('placeholder')).to.equal('common.select');
    expect(select.prop('isSearchable')).to.be.true;
    expect(select.prop('value')).to.equal(defaults.options[0]);
  });

  it('Select onChange calls prop onChange', () => {
    const onChange = simple.mock();
    const select = getWrapper({ onChange }).find(Select);
    expect(select).to.have.length(1);
    select.prop('onChange')(defaults.options[1], {});
    expect(onChange.callCount).to.equal(1);
    expect(onChange.lastCall.args[0]).to.deep.equal(defaults.options[1]);
  });

  it('Select onChange calls prop onChange when clear multi selected field', () => {
    const onChange = simple.mock();
    const multiSelect = getWrapper({ onChange, isMulti: true }).find(Select);
    expect(multiSelect).to.have.length(1);
    multiSelect.prop('onChange')(defaults.options, { action: 'clear' });
    expect(onChange.callCount).to.equal(1);
    expect(onChange.lastCall.args[0]).to.deep.equal([]);
  });

  it('Select onChange calls prop onChange when clear non multi selected field', () => {
    const onChange = simple.mock();
    const select = getWrapper({ onChange }).find(Select);
    expect(select).to.have.length(1);
    select.prop('onChange')(defaults.options, { action: 'clear' });
    expect(onChange.callCount).to.equal(1);
    expect(onChange.lastCall.args[0]).to.deep.equal({});
  });

  it('Select onChange calls prop onChange as fallback', () => {
    const onChange = simple.mock();
    const select = getWrapper({ onChange }).find(Select);
    expect(select).to.have.length(1);
    select.prop('onChange')(defaults.options, { action: 'foo' });
    expect(onChange.callCount).to.equal(1);
  });

  it('call props onChange with multi select if isMulti is true', () => {
    const onChange = simple.mock();
    const select = getWrapper({ onChange, isMulti: true }).find(Select);

    expect(select).to.have.length(1);
    select.prop('onChange')(defaults.options, {});
    expect(onChange.callCount).to.equal(1);
    expect(onChange.lastCall.args[0]).to.deep.equal(defaults.options);
  });

  describe('getValue', () => {
    it('fill selected option when default value is passed in', () => {
      const wrapper = getWrapper({});
      const selectedOption = wrapper.instance().getValue(
        defaults.options[0].value, defaults.options);
      expect(selectedOption).to.deep.equal(defaults.options[0]);
    });

    it('return underfined if value is not exist in any options', () => {
      const wrapper = getWrapper({});
      const selectedOption = wrapper.instance().getValue('foo', defaults.options);
      expect(selectedOption).to.be.undefined;
    });

    it('return array of options if value is array', () => {
      const wrapper = getWrapper({});
      const selectedOption = wrapper.instance().getValue(['filter-1', 'filter-2'], defaults.options);
      expect(selectedOption).to.deep.equal(defaults.options);
    });
  });
});
<|endoftext|>