<commit_before>DocsApp
.directive('layoutAlign', function() { return angular.noop; })
.directive('layout', function() { return angular.noop; })
.directive('docsDemo', [
  '$mdUtil',
function() {
  return {
    restrict: 'E',
    scope: true,
    templateUrl: 'partials/docs-demo.tmpl.html',
    transclude: true,
    controller: ['$scope', '$element', '$attrs', '$interpolate', 'codepen', DocsDemoCtrl],
    controllerAs: 'demoCtrl',
    bindToController: true
  };

  function DocsDemoCtrl($scope, $element, $attrs, codepen) {
    var self = this;

    self.interpolateCode = angular.isDefined($attrs.interpolateCode);

    $attrs.$observe('demoTitle', function(value) {
      self.demoTitle = value;
    });

    $attrs.$observe('demoId', function(value) {
      self.demoId = value;
    });

    $attrs.$observe('demoModule', function(value) {
      self.demoModule = value;
    });

    self.files = {
      css: [], js: [], html: []
    };

    self.addFile = function(name, contentsPromise) {
      var file = {
        name: convertName(name),
        contentsPromise: contentsPromise,
        fileType: name.split('.').pop()
      };
      contentsPromise.then(function(contents) {
        file.contents = contents;
      });

      if (name === 'index.html') {
        self.files.index = file;
      } else if (name === 'readme.html') {
       self.demoDescription = file;
      } else {
        self.files[file.fileType] = self.files[file.fileType] || [];
        self.files[file.fileType].push(file);
      }

      self.orderedFiles = []
        .concat(self.files.index || [])
        .concat(self.files.js || [])
        .concat(self.files.css || [])
        .concat(self.files.html || []);

    };

    self.editOnCodepen = function() {
      codepen.editOnCodepen({
        title: self.demoTitle,
        files: self.files,
        id: self.demoId,
        module: self.demoModule
      });
    };

    function convertName(name) {
      switch(name) {
        case "index.html" : return "HTML";
        case "script.js" : return "JS";
        case "style.css" : return "CSS";
        default : return name;
      }
    }

  }
}])
.directive('demoFile', ['$q', '$interpolate', function($q, $interpolate) {
  return {
    restrict: 'E',
    require: '^docsDemo',
    compile: compile
  };

  function compile(element, attr) {
    var contentsAttr = attr.contents;
    var html = element.html();
    var name = attr.name;
    element.contents().remove();

    return function postLink(scope, element, attr, docsDemoCtrl) {
      docsDemoCtrl.addFile(
        $interpolate(name)(scope),
        $q.when(scope.$eval(contentsAttr) || html)
      );
      element.remove();
    };
  }
}])

.filter('toHtml', ['$sce', function($sce) {
  return function(str) {
    return $sce.trustAsHtml(str);
  };
}]);
<commit_msg>fix(docs): DocsDemoCtrl fixed to interpolate and observe.<commit_after>DocsApp
.directive('layoutAlign', function() { return angular.noop; })
.directive('layout', function() { return angular.noop; })
.directive('docsDemo', ['$mdUtil', function($mdUtil) {
  return {
    restrict: 'E',
    scope: true,
    templateUrl: 'partials/docs-demo.tmpl.html',
    transclude: true,
    controller: ['$scope', '$element', '$attrs', '$interpolate', 'codepen', DocsDemoCtrl],
    controllerAs: 'demoCtrl',
    bindToController: true
  };

  function DocsDemoCtrl($scope, $element, $attrs, $interpolate, codepen) {
    var self = this;

    self.interpolateCode = angular.isDefined($attrs.interpolateCode);
    self.demoId = $interpolate($attrs.demoId || '')($scope.$parent);
    self.demoTitle = $interpolate($attrs.demoTitle || '')($scope.$parent);
    self.demoModule = $interpolate($attrs.demoModule || '')($scope.$parent);

    $attrs.$observe('demoTitle',  function(value) { self.demoTitle  = value || self.demoTitle; });
    $attrs.$observe('demoId',     function(value) { self.demoId     = value || self.demoId; });
    $attrs.$observe('demoModule', function(value) { self.demoModule = value || self.demoModule;  });

    self.files = {
      css: [], js: [], html: []
    };

    self.addFile = function(name, contentsPromise) {
      var file = {
        name: convertName(name),
        contentsPromise: contentsPromise,
        fileType: name.split('.').pop()
      };
      contentsPromise.then(function(contents) {
        file.contents = contents;
      });

      if (name === 'index.html') {
        self.files.index = file;
      } else if (name === 'readme.html') {
       self.demoDescription = file;
      } else {
        self.files[file.fileType] = self.files[file.fileType] || [];
        self.files[file.fileType].push(file);
      }

      self.orderedFiles = []
        .concat(self.files.index || [])
        .concat(self.files.js || [])
        .concat(self.files.css || [])
        .concat(self.files.html || []);

    };

    self.editOnCodepen = function() {
      codepen.editOnCodepen({
        title: self.demoTitle,
        files: self.files,
        id: self.demoId,
        module: self.demoModule
      });
    };

    function convertName(name) {
      switch(name) {
        case "index.html" : return "HTML";
        case "script.js" : return "JS";
        case "style.css" : return "CSS";
        default : return name;
      }
    }

  }
}])
.directive('demoFile', ['$q', '$interpolate', function($q, $interpolate) {
  return {
    restrict: 'E',
    require: '^docsDemo',
    compile: compile
  };

  function compile(element, attr) {
    var contentsAttr = attr.contents;
    var html = element.html();
    var name = attr.name;
    element.contents().remove();

    return function postLink(scope, element, attr, docsDemoCtrl) {
      docsDemoCtrl.addFile(
        $interpolate(name)(scope),
        $q.when(scope.$eval(contentsAttr) || html)
      );
      element.remove();
    };
  }
}])

.filter('toHtml', ['$sce', function($sce) {
  return function(str) {
    return $sce.trustAsHtml(str);
  };
}]);
<|endoftext|>


<commit_before>
module.exports = {
   "extends": "google",
   "parserOptions": {
     "ecmaVersion": 6
   },
   "rules": {
     "require-jsdoc": 0,
     "no-var": 0,
     "valid-jsdoc": 0,
     "max-len": 0,
     "comma-dangle": 0,
     "quotes": 0,
     "camelcase": 0,
     "eol-last": 0,
     "space-before-function-paren": 0,
     "padded-blocks": 0
   }
};<commit_msg>Update linter settings<commit_after>
module.exports = {
   "extends": "google",
   "parserOptions": {
     "ecmaVersion": 6
   },
   "rules": {
     "require-jsdoc": 0,
     "no-var": 0,
     "valid-jsdoc": 0,
     "max-len": 0,
     "comma-dangle": 0,
     "quotes": 0,
     "camelcase": 0,
     "eol-last": 0,
     "space-before-function-paren": 0,
     "padded-blocks": 0,
     "max-statements": 1
   }
};<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { connect } from 'react-redux';
import styles from './issueCards.css';
import { closeUserIssue } from '../../actions/githubActions/closeIssueAction';
import { fetchUserComments } from '../../actions/githubActions/getIssueCommentsAction';
import ModalIssueComment from '../Modal/comment_modal';
import { addUserComment } from '../../actions/githubActions/addCommentAction';
import IssuePullModal from '../Modal/newissuePull_Modal';
import { convertDate } from '../EventFeed/logical_solutions';
import { addNewAssignees } from '../../actions/githubActions/addAssigneesAction';
import { removeNewAssignees } from '../../actions/githubActions/removeAssigneesAction';

class IssueCard extends Component {
  state = {
    isShowingModal: false,
    issuesLoaded: false,
    commentsLoaded: false,
    assigneesLoaded: false,
    issues: null,
    issueComments: null,
    newCommentText: '',
    currentIssueNumber: '',
    currentModalState: '',
    assigneeData: null,
  }
  componentDidMount() {
    // console.log('INTIAL COMMENTS DATA TO SEND OFF ', this.props.repoOwner, this.props.repoName);
    this.props.issues.map((issue) => {
      this.props.fetchUserComments(this.props.repoOwner, this.props.repoName, issue.number, this.props.git_token);
    });
  }
  componentWillReceiveProps(nextProps) {
    // console.log(' WHEN DO WE GET NEW ISSUES?', nextProps.issueComments);
    // console.log("this should show projects connected in state", nextProps.currentProject);
    const { issueComments, issues, repoName, repoOwner } = nextProps;
    // console.log('new issues coming in on next props to check for new assignees', issues);
    // this.setState({ issueComments });
    // console.log('State Prios in Card itself need to see if this is being modified', this.state.issues);
    // console.log('AM I geting the new issue Array', issues);
    // console.log('Here are next props in Issue card', repoName, repoOwner);
    const commentsLength = Object.keys(issueComments).length;
    const issuesLength = issues.length;
    if (this.state.issues !== null) {
      if (this.props.issues.length !== issues.length) {
        this.setState({ issuesLoaded: false });
        const assigneeData = this.props.issues.map((issue) => issue.assignees);
        // console.log('SETTING ISSUES STATE AS WE READ', this.state.issuesLoaded);
        this.setState({ issues, issuesLoaded: true, assigneeData, assigneesLoaded: true });
        issues.map((issue) => {
          this.props.fetchUserComments(this.props.repoOwner, this.props.repoName, issue.number, this.props.git_token);
        });
        // console.log('Now this is state again and should be modified thus causing a re render', this.state.issues, this.state.issuesLoaded);
      }
    }
    if (commentsLength === issuesLength) {
      // console.log('Issues in Issue Card from next props', issues);
      // console.log('SETTING ISSUES STATE AS WE READ', this.state.issuesLoaded);
      const assigneeData = this.props.issues.map((issue) => issue.assignees);
      this.setState({ issueComments, issues, commentsLoaded: true, issuesLoaded: true, assigneeData, assigneesLoaded: true });
      // console.log('Now this is state again and should be modified thus causing a re render', this.state.issues, this.state.issuesLoaded);
    }
    if (this.state.issueComments !== null) {
      if (issueComments.length !== this.state.issueComments.length) {
        // console.log('do these comments reset?????');
        this.setState({ issueComments });
      }
    }
  }
handleModalStateChange = (state) => {
  this.setState({ currentModalState: state });
}
modifyTextState = (event) => {
  this.setState({ newCommentText: event.target.value });
}
handleAddNewComment = () => {
  const { currentIssue } = this.state;
  this.props.addUserComment(this.props.repoOwner, this.props.repoName, currentIssue, this.state.newCommentText, this.props.git_token);
  this.setState({ newCommentText: '' });
  this.handleClose();
}
handleClick = (currentIssue) => this.setState({ isShowingModal: true, currentIssue })
handleClose = () => this.setState({ isShowingModal: false })
handleCloseIssue = (login, repoName, issueNum, token) => {
// console.log('PASSING TO CLOSE ISSUE', login, repoName, issueNum, token);
  this.props.closeUserIssue(login, repoName, issueNum, token);
}
shouldComponentUpdate(nextProps, nextState) {
  return true;
}
// this function handles adding new assignees, closing the modal, and refreshing the page
handleAddAssignees = (assignees) => {
  this.setState({ assigneesLoaded: false });
  this.props.addNewAssignees(this.props.repoOwner, this.props.repoName, this.props.currentIssueNumber, assignees, this.props.git_token);
  this.props.handleIssuePullClose();
  setTimeout(this.props.handleRefresh(), 2000);
}
handleRemoveAssignees = (assignees) => {
  this.setState({ assigneesLoaded: false });
  this.props.removeNewAssignees(this.props.repoOwner, this.props.repoName, this.props.currentIssueNumber, assignees, this.props.git_token);
  this.props.handleIssuePullClose();
  setTimeout(this.props.handleRefresh(), 2000);
}
render() {
  // console.log('STATE of issues at render', this.state.issues);
  // console.log('issue card mocal state', this.props.modalState);
  // console.log('Expanded card State', this.state.expandedCards);
  const { issuesLoaded, commentsLoaded, assigneesLoaded } = this.state;
  // console.log('Card state issues!!!!!!!!!!!!!!!!!!!!', this.state.issues);
  // console.log('Here are the expanded cards', this.state.expandedCards);
  // console.log('Here aremy issue comments', this.state.issueComments);
  if (issuesLoaded && commentsLoaded && assigneesLoaded) {
    const { issues, issueComments, isShowingModal } = this.state;
    return (
      //

      <div className={`card-group ${styles.mainCont}`}>
        {issues.map((issue, i) => (

            <div className={`card ${styles.boxShad}`}>
              <div className="card-header" data-toggle="collapse" href={`#collapse${issue.number}`} >{`${issue.title} -  ${issue.pull_request ? 'Pull Request' : 'Issue'} #${issue.number}`}

              <div id={`collapse${issue.number}`} className={`card-block collapse`}>
                <img className={`${styles.avatarFix} pull-left`} src={issue.user.avatar_url} alt="user" />
                <h6 className={`card-title pull-left ${styles.titleBump}`}>{`Opened By ${issue.user.login}`}

{issue.body}

                  {issueComments[issue.number].map((comment) => (

{ `Comment by ${comment.user.login}${convertDate(comment.created_at)}` }

{ comment.body }

                  ),
                  )
                  }

Current Assignees:

                  { this.state.assigneeData[i].map((assignee) => (

                      <img className={`${styles.avatarFix} pull-left`} src={assignee.avatar_url} alt="user" />

                  ))}

                  <div style={{ marginRight: 5 }} className={`btn btn-primary`} onClick={() => this.handleClick(issue.number)}>Comment

                  <div style={{ marginRight: 5 }} className={`btn btn-primary`} onClick={() => this.handleCloseIssue(this.props.repoOwner, this.props.repoName, issue.number, this.props.git_token)}>Close

                  <div className={`btn btn-primary`} onClick={() => this.props.handleModalState('assignee', issue.number)}>Assignees

        ))}
        <IssuePullModal assigneeData={this.state.assigneeData} modalState={this.props.modalState} handleCreateIssueData={this.props.handleCreateIssueData} collabs={this.props.collabs} isShowing={this.props.issueModalState} handleAddAssignees={this.handleAddAssignees} handleIssuePullClick={this.props.handleIssuePullClick} handleIssuePullClose={this.props.handleIssuePullClose} handleRemoveAssignees={this.handleRemoveAssignees} />

        <ModalIssueComment
          changeHandler={this.modifyTextState}
          handleClick={this.handleClick}
          handleClose={this.handleClose}
          isShowingModal={this.state.isShowingModal}
          value={this.state.newCommentText}
          handleAddComment={this.handleAddNewComment}
        />

    );
  }
  return (

        <img className={`center-block ${styles.loaderImageThree}`} src="./images/uTile_black_loader_100.gif" alt="loader" />

Loading...

  );
}
}

// export default IssueCard;

export default connect((state, ownProps) => ({
  collabs: state.collabs.collabs,
  closedIssData: state.issue,
  currentProject: state.repos.currentProject,
  issueComments: state.comments.issueComments,
  git_profile: state.auth.git_profile,
  git_token: state.auth.github_token,
  // branches: state.branches.branches,
}), (dispatch) => ({
  closeUserIssue: (userId, repoName, issueNum, token) => dispatch(closeUserIssue(userId, repoName, issueNum, token)),
  fetchUserComments: (userId, repoName, issueNum, token) => dispatch(fetchUserComments(userId, repoName, issueNum, token)),
  addUserComment: (userName, repoName, issueNum, body, token) => dispatch(addUserComment(userName, repoName, issueNum, body, token)),
  addNewAssignees: (userName, repoName, issueNum, assignees, token) => dispatch(addNewAssignees(userName, repoName, issueNum, assignees, token)),
  removeNewAssignees: (userName, repoName, issueNum, assignees, token) => dispatch(removeNewAssignees(userName, repoName, issueNum, assignees, token)),
}))(IssueCard);
<commit_msg>added in markdown support for comment body and for issue body<commit_after>import React, { Component } from 'react';
import { connect } from 'react-redux';
import styles from './issueCards.css';
import { closeUserIssue } from '../../actions/githubActions/closeIssueAction';
import { fetchUserComments } from '../../actions/githubActions/getIssueCommentsAction';
import ModalIssueComment from '../Modal/comment_modal';
import { addUserComment } from '../../actions/githubActions/addCommentAction';
import IssuePullModal from '../Modal/newissuePull_Modal';
import { convertDate } from '../EventFeed/logical_solutions';
import { addNewAssignees } from '../../actions/githubActions/addAssigneesAction';
import { removeNewAssignees } from '../../actions/githubActions/removeAssigneesAction';
import Markdown from 'react-remarkable';

class IssueCard extends Component {
  state = {
    isShowingModal: false,
    issuesLoaded: false,
    commentsLoaded: false,
    assigneesLoaded: false,
    issues: null,
    issueComments: null,
    newCommentText: '',
    currentIssueNumber: '',
    currentModalState: '',
    assigneeData: null,
  }
  componentDidMount() {
    // console.log('INTIAL COMMENTS DATA TO SEND OFF ', this.props.repoOwner, this.props.repoName);
    this.props.issues.map((issue) => {
      this.props.fetchUserComments(this.props.repoOwner, this.props.repoName, issue.number, this.props.git_token);
    });
  }
  componentWillReceiveProps(nextProps) {
    // console.log(' WHEN DO WE GET NEW ISSUES?', nextProps.issueComments);
    // console.log("this should show projects connected in state", nextProps.currentProject);
    const { issueComments, issues, repoName, repoOwner } = nextProps;
    // console.log('new issues coming in on next props to check for new assignees', issues);
    // this.setState({ issueComments });
    // console.log('State Prios in Card itself need to see if this is being modified', this.state.issues);
    // console.log('AM I geting the new issue Array', issues);
    // console.log('Here are next props in Issue card', repoName, repoOwner);
    const commentsLength = Object.keys(issueComments).length;
    const issuesLength = issues.length;
    if (this.state.issues !== null) {
      if (this.props.issues.length !== issues.length) {
        this.setState({ issuesLoaded: false });
        const assigneeData = this.props.issues.map((issue) => issue.assignees);
        // console.log('SETTING ISSUES STATE AS WE READ', this.state.issuesLoaded);
        this.setState({ issues, issuesLoaded: true, assigneeData, assigneesLoaded: true });
        issues.map((issue) => {
          this.props.fetchUserComments(this.props.repoOwner, this.props.repoName, issue.number, this.props.git_token);
        });
        // console.log('Now this is state again and should be modified thus causing a re render', this.state.issues, this.state.issuesLoaded);
      }
    }
    if (commentsLength === issuesLength) {
      // console.log('Issues in Issue Card from next props', issues);
      // console.log('SETTING ISSUES STATE AS WE READ', this.state.issuesLoaded);
      const assigneeData = this.props.issues.map((issue) => issue.assignees);
      this.setState({ issueComments, issues, commentsLoaded: true, issuesLoaded: true, assigneeData, assigneesLoaded: true });
      // console.log('Now this is state again and should be modified thus causing a re render', this.state.issues, this.state.issuesLoaded);
    }
    if (this.state.issueComments !== null) {
      if (issueComments.length !== this.state.issueComments.length) {
        // console.log('do these comments reset?????');
        this.setState({ issueComments });
      }
    }
  }
handleModalStateChange = (state) => {
  this.setState({ currentModalState: state });
}
modifyTextState = (event) => {
  this.setState({ newCommentText: event.target.value });
}
handleAddNewComment = () => {
  const { currentIssue } = this.state;
  this.props.addUserComment(this.props.repoOwner, this.props.repoName, currentIssue, this.state.newCommentText, this.props.git_token);
  this.setState({ newCommentText: '' });
  this.handleClose();
}
handleClick = (currentIssue) => this.setState({ isShowingModal: true, currentIssue })
handleClose = () => this.setState({ isShowingModal: false })
handleCloseIssue = (login, repoName, issueNum, token) => {
// console.log('PASSING TO CLOSE ISSUE', login, repoName, issueNum, token);
  this.props.closeUserIssue(login, repoName, issueNum, token);
}
shouldComponentUpdate(nextProps, nextState) {
  return true;
}
// this function handles adding new assignees, closing the modal, and refreshing the page
handleAddAssignees = (assignees) => {
  this.setState({ assigneesLoaded: false });
  this.props.addNewAssignees(this.props.repoOwner, this.props.repoName, this.props.currentIssueNumber, assignees, this.props.git_token);
  this.props.handleIssuePullClose();
  setTimeout(this.props.handleRefresh(), 2000);
}
handleRemoveAssignees = (assignees) => {
  this.setState({ assigneesLoaded: false });
  this.props.removeNewAssignees(this.props.repoOwner, this.props.repoName, this.props.currentIssueNumber, assignees, this.props.git_token);
  this.props.handleIssuePullClose();
  setTimeout(this.props.handleRefresh(), 2000);
}
render() {
  // console.log('STATE of issues at render', this.state.issues);
  // console.log('issue card mocal state', this.props.modalState);
  // console.log('Expanded card State', this.state.expandedCards);
  const { issuesLoaded, commentsLoaded, assigneesLoaded } = this.state;
  console.log('Card state issues!!!!!!!!!!!!!!!!!!!!', this.state.issues);
  // console.log('Here are the expanded cards', this.state.expandedCards);
  // console.log('Here aremy issue comments', this.state.issueComments);
  if (issuesLoaded && commentsLoaded && assigneesLoaded) {
    const { issues, issueComments, isShowingModal } = this.state;
    return (
      //

      <div className={`card-group ${styles.mainCont}`}>
        {issues.map((issue, i) => (

            <div className={`card ${styles.boxShad}`}>
              <div className="card-header" data-toggle="collapse" href={`#collapse${issue.number}`} >{`${issue.title} -  ${issue.pull_request ? 'Pull Request' : 'Issue'} #${issue.number}`}

              <div id={`collapse${issue.number}`} className={`card-block collapse`}>
                <img className={`${styles.avatarFix} pull-left`} src={issue.user.avatar_url} alt="user" />
                <h6 className={`card-title pull-left ${styles.titleBump}`}>{`Opened By ${issue.user.login}`}

                <Markdown className="card-text" source={`${issue.body}`} />

                  {issueComments[issue.number].map((comment) => (

{ `Comment by ${comment.user.login}${convertDate(comment.created_at)}` }

                      <Markdown className="card-text" source={`${comment.body}`} />

                  ),
                  )
                  }

Current Assignees:

                  { this.state.assigneeData[i].map((assignee) => (

                      <img className={`${styles.avatarFix} pull-left`} src={assignee.avatar_url} alt="user" />

                  ))}

                  <div style={{ marginRight: 5 }} className={`btn btn-primary`} onClick={() => this.handleClick(issue.number)}>Comment

                  <div style={{ marginRight: 5 }} className={`btn btn-primary`} onClick={() => this.handleCloseIssue(this.props.repoOwner, this.props.repoName, issue.number, this.props.git_token)}>Close

                  <div className={`btn btn-primary`} onClick={() => this.props.handleModalState('assignee', issue.number)}>Assignees

        ))}
        <IssuePullModal assigneeData={this.state.assigneeData} modalState={this.props.modalState} handleCreateIssueData={this.props.handleCreateIssueData} collabs={this.props.collabs} isShowing={this.props.issueModalState} handleAddAssignees={this.handleAddAssignees} handleIssuePullClick={this.props.handleIssuePullClick} handleIssuePullClose={this.props.handleIssuePullClose} handleRemoveAssignees={this.handleRemoveAssignees} />

        <ModalIssueComment
          changeHandler={this.modifyTextState}
          handleClick={this.handleClick}
          handleClose={this.handleClose}
          isShowingModal={this.state.isShowingModal}
          value={this.state.newCommentText}
          handleAddComment={this.handleAddNewComment}
        />

    );
  }
  return (

        <img className={`center-block ${styles.loaderImageThree}`} src="./images/uTile_black_loader_100.gif" alt="loader" />
        {setTimeout(()=>{
          return (

It does not looks like there are any issues currently.

        );
        }, 5000)}

  );
}
}

// export default IssueCard;

export default connect((state, ownProps) => ({
  collabs: state.collabs.collabs,
  closedIssData: state.issue,
  currentProject: state.repos.currentProject,
  issueComments: state.comments.issueComments,
  git_profile: state.auth.git_profile,
  git_token: state.auth.github_token,
  // branches: state.branches.branches,
}), (dispatch) => ({
  closeUserIssue: (userId, repoName, issueNum, token) => dispatch(closeUserIssue(userId, repoName, issueNum, token)),
  fetchUserComments: (userId, repoName, issueNum, token) => dispatch(fetchUserComments(userId, repoName, issueNum, token)),
  addUserComment: (userName, repoName, issueNum, body, token) => dispatch(addUserComment(userName, repoName, issueNum, body, token)),
  addNewAssignees: (userName, repoName, issueNum, assignees, token) => dispatch(addNewAssignees(userName, repoName, issueNum, assignees, token)),
  removeNewAssignees: (userName, repoName, issueNum, assignees, token) => dispatch(removeNewAssignees(userName, repoName, issueNum, assignees, token)),
}))(IssueCard);
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2008-2012 The Open Source Geospatial Foundation
 *
 * Published under the BSD license.
 * See http://svn.geoext.org/core/trunk/geoext/license.txt for the full text
 * of the license.
 */

/** api: (define)
 *  module = GeoExt.plugins
 *  class = PrintProviderField
 *  base_link = `Ext.util.Observable <http://dev.sencha.com/deploy/dev/docs/?class=Ext.util.Observable>`_
 */

/** api: example
 *  A form with combo boxes for layout and resolution, and a text field for a
 *  map title. The latter is a custom parameter to the print module, which is
 *  a default for all print pages. For setting custom parameters on the page
 *  level, use :class:`GeoExt.plugins.PrintPageField`):
 *
 *  .. code-block:: javascript
 *
 *      var printProvider = new GeoExt.data.PrintProvider({
 *          capabilities: printCapabilities
 *      });
 *      new Ext.form.FormPanel({
 *          renderTo: "form",
 *          width: 200,
 *          height: 300,
 *          items: [{
 *              xtype: "combo",
 *              displayField: "name",
 *              store: printProvider.layouts, // printProvider.layout
 *              fieldLabel: "Layout",
 *              typeAhead: true,
 *              mode: "local",
 *              forceSelection: true,
 *              triggerAction: "all",
 *              selectOnFocus: true,
 *              plugins: new GeoExt.plugins.PrintProviderField({
 *                  printProvider: printProvider
 *              })
 *          }, {
 *              xtype: "combo",
 *              displayField: "name",
 *              store: printProvider.dpis, // printProvider.dpi
 *              fieldLabel: "Resolution",
 *              typeAhead: true,
 *              mode: "local",
 *              forceSelection: true,
 *              triggerAction: "all",
 *              selectOnFocus: true,
 *              plugins: new GeoExt.plugins.PrintProviderField({
 *                  printProvider: printProvider
 *              })
 *          }, {
 *              xtype: "textfield",
 *              name: "mapTitle", // printProvider.customParams.mapTitle
 *              fieldLabel: "Map Title",
 *              plugins: new GeoExt.plugins.PrintProviderField({
 *                  printProvider: printProvider
 *              })
 *          }]
 *      }):
 */

/** api: constructor
 *  .. class:: PrintProviderField
 *
 *  A plugin for ``Ext.form.Field`` components which provides synchronization
 *  with a :class:`GeoExt.data.PrintProvider`.
 */

Ext.define('GeoExt.plugins.PrintProviderField', {
    mixins: {
        observable: 'Ext.util.Observable'
    },
    requires: ['GeoExt.data.PrintProvider', 'Ext.form.field.ComboBox'],
    alias : 'widget.gx_printproviderfield',
    alternateClassName : 'GeoExt.PrintProviderField',

    /** api: config[printProvider]
     *  ``GeoExt.data.PrintProvider`` The print provider to use with this
     *  plugin's field. Not required if set on the owner container of the
     *  field.
     */

    /** private: property[target]
     *  ``Ext.form.Field`` This plugin's target field.
     */
    target: null,

    /** private: method[constructor]
     */
    constructor: function(config) {
        this.initialConfig = config;
        Ext.apply(this, config);

        this.callParent(arguments);
    },

    /** private: method[init]
     *  :param target: ``Ext.form.Field`` The component that this plugin
     *      extends.
     */
    init: function(target) {
        this.target = target;
        var onCfg = {
            scope: this,
            "render": this.onRender,
            "beforedestroy": this.onBeforeDestroy
        };
        onCfg[target instanceof Ext.form.ComboBox ? "select" : "change"] =
            this.onFieldChange;
        target.on(onCfg);
    },

    /** private: method[onRender]
     *  :param field: ``Ext.Form.Field``
     *
     *  Handler for the target field's "render" event.
     */
    onRender: function(field) {
        var printProvider = this.printProvider || field.ownerCt.printProvider;
        if(field.store === printProvider.layouts) {
            field.setValue(printProvider.layout.get(field.displayField));
            printProvider.on({
                "layoutchange": this.onProviderChange,
                scope: this
            });
        } else if(field.store === printProvider.dpis) {
            field.setValue(printProvider.dpi.get(field.displayField));
            printProvider.on({
                "dpichange": this.onProviderChange,
                scope: this
            });
        } else if(field.initialConfig.value === undefined) {
            field.setValue(printProvider.customParams[field.name]);
        }
    },

    /** private: method[onFieldChange]
     *  :param field: ``Ext.form.Field``
     *  :param record: ``Ext.data.Record`` Optional.
     *
     *  Handler for the target field's "valid" or "select" event.
     */
    onFieldChange: function(field, records) {
        var record;
        if (Ext.isArray(records)) {
            record = records[0];
        } else {
            record = records;
        }
        var printProvider = this.printProvider || field.ownerCt.printProvider;
        var value = field.getValue();
        this._updating = true;
        if(record) {
            switch(field.store) {
                case printProvider.layouts:
                    printProvider.setLayout(record);
                    break;
                case printProvider.dpis:
                    printProvider.setDpi(record);
                    break;
            }
        } else {
            printProvider.customParams[field.name] = value;
        }
        delete this._updating;
    },

    /** private: method[onProviderChange]
     *  :param printProvider: :class:`GeoExt.data.PrintProvider`
     *  :param rec: ``Ext.data.Record``
     *
     *  Handler for the printProvider's dpichange and layoutchange event
     */
    onProviderChange: function(printProvider, rec) {
        if(!this._updating) {
            this.target.setValue(rec.get(this.target.displayField));
        }
    },

    /** private: method[onBeforeDestroy]
     */
    onBeforeDestroy: function() {
        var target = this.target;
        target.un("beforedestroy", this.onBeforeDestroy, this);
        target.un("render", this.onRender, this);
        target.un("select", this.onFieldChange, this);
        target.un("valid", this.onFieldChange, this);
        var printProvider = this.printProvider || target.ownerCt.printProvider;
        printProvider.un("layoutchange", this.onProviderChange, this);
        printProvider.un("dpichange", this.onProviderChange, this);
    }

});

<commit_msg>API documentation.<commit_after>/**
 * Copyright (c) 2008-2012 The Open Source Geospatial Foundation
 *
 * Published under the BSD license.
 * See http://svn.geoext.org/core/trunk/geoext/license.txt for the full text
 * of the license.
 */

/**
 *  @class GeoExt.plugins.PrintProviderField
 *
 *  A plugin for Ext.form.Field components which provides synchronization
 *  with a GeoExt.data.PrintProvider.
 *
 *  A form with combo boxes for layout and resolution, and a text field for a
 *  map title. The latter is a custom parameter to the print module, which is
 *  a default for all print pages. For setting custom parameters on the page
 *  level, use GeoExt.plugins.PrintPageField.
 *
 *
 *     var printProvider = Ext.create('GeoExt.data.PrintProvider', {
 *         capabilities: printCapabilities
 *     });
 *     Ext.create('Ext.form.FormPanel', {
 *         renderTo: "form",
 *         width: 200,
 *         height: 300,
 *         items: [{
 *             xtype: "combo",
 *             displayField: "name",
 *             store: printProvider.layouts, // printProvider.layout
 *             fieldLabel: "Layout",
 *             typeAhead: true,
 *             mode: "local",
 *             forceSelection: true,
 *             triggerAction: "all",
 *             selectOnFocus: true,
 *             plugins: Ext.create('GeoExt.plugins.PrintProviderField', {
 *                 printProvider: printProvider
 *             })
 *         }, {
 *             xtype: "combo",
 *             displayField: "name",
 *             store: printProvider.dpis, // printProvider.dpi
 *             fieldLabel: "Resolution",
 *             typeAhead: true,
 *             mode: "local",
 *             forceSelection: true,
 *             triggerAction: "all",
 *             selectOnFocus: true,
 *             plugins: Ext.create('GeoExt.plugins.PrintProviderField', {
 *                 printProvider: printProvider
 *             })
 *         }, {
 *             xtype: "textfield",
 *             name: "mapTitle", // printProvider.customParams.mapTitle
 *             fieldLabel: "Map Title",
 *             plugins: Ext.create('GeoExt.plugins.PrintProviderField', {
 *                 printProvider: printProvider
 *             })
 *         }]
 *     }):
 */
Ext.define('GeoExt.plugins.PrintProviderField', {
    mixins: {
        observable: 'Ext.util.Observable'
    },
    requires: ['GeoExt.data.PrintProvider', 'Ext.form.field.ComboBox'],
    alias : 'widget.gx_printproviderfield',
    alternateClassName : 'GeoExt.PrintProviderField',

    /**
     * @cfg {GeoExt.data.PrintProvider} printProvider
     * The print provider to use with this
     * plugin's field. Not required if set on the owner container of the
     * field.
     */

    /**
     * @private
     * @property {Ext.form.Field} target
     * This plugin's target field.
     */
    target: null,

    /**
     * @private
     */
    constructor: function(config) {
        this.initialConfig = config;
        Ext.apply(this, config);

        this.callParent(arguments);
    },

    /**
     * @private
     * @param {Ext.form.Field} target The component that this plugin extends.
     */
    init: function(target) {
        this.target = target;
        var onCfg = {
            scope: this,
            "render": this.onRender,
            "beforedestroy": this.onBeforeDestroy
        };
        onCfg[target instanceof Ext.form.ComboBox ? "select" : "change"] =
            this.onFieldChange;
        target.on(onCfg);
    },

    /**
     * Handler for the target field's "render" event.
     *
     * @private
     * @param {Ext.Form.Field} field
     */
    onRender: function(field) {
        var printProvider = this.printProvider || field.ownerCt.printProvider;
        if(field.store === printProvider.layouts) {
            field.setValue(printProvider.layout.get(field.displayField));
            printProvider.on({
                "layoutchange": this.onProviderChange,
                scope: this
            });
        } else if(field.store === printProvider.dpis) {
            field.setValue(printProvider.dpi.get(field.displayField));
            printProvider.on({
                "dpichange": this.onProviderChange,
                scope: this
            });
        } else if(field.initialConfig.value === undefined) {
            field.setValue(printProvider.customParams[field.name]);
        }
    },

    /**
     * Handler for the target field's "change" or "select" event.
     *
     * @private
     * @param {Ext.form.Field} field
     * @param {Ext.data.Record} record Optional.
     */
    onFieldChange: function(field, records) {
        var record;
        if (Ext.isArray(records)) {
            record = records[0];
        } else {
            record = records;
        }
        var printProvider = this.printProvider || field.ownerCt.printProvider;
        var value = field.getValue();
        this._updating = true;
        if(record) {
            switch(field.store) {
                case printProvider.layouts:
                    printProvider.setLayout(record);
                    break;
                case printProvider.dpis:
                    printProvider.setDpi(record);
                    break;
            }
        } else {
            printProvider.customParams[field.name] = value;
        }
        delete this._updating;
    },

    /**
     * Handler for the printProvider's dpichange and layoutchange event
     *
     * @private
     * @param {GeoExt.data.PrintProvider}  printProvider
     * @param {Ext.data.Record}  rec
     */
    onProviderChange: function(printProvider, rec) {
        if(!this._updating) {
            this.target.setValue(rec.get(this.target.displayField));
        }
    },

    /**
     * @private
     */
    onBeforeDestroy: function() {
        var target = this.target;
        target.un("beforedestroy", this.onBeforeDestroy, this);
        target.un("render", this.onRender, this);
        target.un("select", this.onFieldChange, this);
        target.un("valid", this.onFieldChange, this);
        var printProvider = this.printProvider || target.ownerCt.printProvider;
        printProvider.un("layoutchange", this.onProviderChange, this);
        printProvider.un("dpichange", this.onProviderChange, this);
    }

});

<|endoftext|>


<commit_before>module.exports = function (grunt) {
    /**
     * Project configuration
     */
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        concat: {
            js_distribution: {
                src: ['var/public/bower/jquery/dist/jquery.min.js',
                    'var/public/bower/bootstrap/dist/js/bootstrap.min.js',
                    'var/public/bower/particles.js/particles.js',
                    'var/public/assets/scripts/bootstrap.js'],
                dest: 'dist/script.js'
            }
        },

        /*
            Deployment
         */
        git_deploy: {
            your_target: {
                options: {
                    url: 'https://github.com/basvandriel/basvandriel.nl.git'
                },
                src: './dist/'
            }
        }
    });

    /**
     * Load tasks
     */
    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-git-deploy');

    // Default tasks
    grunt.registerTask('default', []);

    /**
     * Deploy to a server
     */
    grunt.registerTask('deploy', "Deploys to a server", function () {

    });
};<commit_msg>change<commit_after>module.exports = function (grunt) {
    /**
     * Project configuration
     */
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),

        /*

         */
        uglify: {
            my_target: {
                files: {
                    'dist/public/assets/scripts/libraries.min.js': ['var/public/bower/jquery/dist/jquery.min.js',
                        'var/public/bower/bootstrap/dist/js/bootstrap.min.js',
                        'var/public/bower/particles.js/particles.js'],
                    'dist/public/assets/scripts/bootstrap.min.js': ['var/public/assets/scripts/bootstrap.js']
                }
            }
        },

        /*
         Deployment
         */
        git_deploy: {
            your_target: {
                options: {
                    url: 'https://github.com/basvandriel/basvandriel.nl.git'
                },
                src: './dist/'
            }
        }
    });

    /**
     * Load tasks
     */
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-git-deploy');

    // Default tasks
    grunt.registerTask('default', []);

    /**
     * Deploy to a server
     */
    grunt.registerTask('deploy', "Deploys to a server", function () {

    });
};<|endoftext|>


<commit_before>/* globals currentRequest, popoverLocalInit, AltinnModal */
/* globals AltinnModal:true, AltinnLoader */
AltinnModal = {
  closeModal: function(settings) {
    $('body').removeClass('a-modal-background-error a-displayNav');
    $('body').removeClass('a-modal-background-success');
    $(settings.target).modal('hide');
    $('body').append($('.a-stickyHelp-container'));
  },

  loadModal: function(settings) {
    var currentRequest = $.ajax({
      url: settings.url,
      beforeSend: function() {
        if (typeof currentRequest !== 'undefined') {
          currentRequest.abort();
        }

        AltinnLoader.addLoader($('body'));
      },
      data: settings.data
    }).always(function() {
    }).done(function(data) {
      var modalPage = $('<div/>', {
        class: 'modalPage',
        html: data
      });
      var page = $('<div/>', {
        class: 'a-page a-current-page',
        data: {
          pageIndex: 1,
          isSuccess: settings.isSuccess,
          isError: settings.isError,
          showModalNav: settings.showModalNav
        },
        html: modalPage
      });

      $('body').removeClass('a-modal-background-error a-displayNav');
      $('body').removeClass('a-modal-background-success');

      // if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {
      //   goToModalHeader();
      // }

      $(settings.target + ' .a-modal-content-target').append(page);
      $(settings.target).find('.a-current-page').first().data().enableDirtyPopover = settings.enableDirtyPopover;

      // Initialize with backdrop: static to prevent modal from closing when clicking outside,
      // and keyboard: false to prevent ESC from closing the modal
      $(settings.target).modal({
        backdrop: 'static',
        keyboard: false
      });

      $(settings.target).on('hidden.bs.modal', function() {
        $(settings.target + ' .a-modal-content-target').empty();
        $(settings.target).attr('aria-hidden', true);
      });

      $(settings.target).on('shown.bs.modal', function() {
        $(settings.target).removeAttr('aria-hidden');
      });
      popoverLocalInit();

      if (settings.isError) {
        $('body').addClass('a-modal-background-error');
        if (settings.showModalNav) {
          $('body').addClass('a-displayNav');
        }
      } else if (settings.isSuccess) {
        $('body').addClass('a-modal-background-success');
      }

      AltinnLoader.removeLoader($('body'));
      $(settings.target).on('transitionend', function() {
        $(settings.target).append($('.a-stickyHelp-container'));
      });
    });
  },

  nextModalPageWithContent: function(settings) {
    var current;
    var modalPage = $('<div/>', {
      class: 'modalPage',
      html: settings.content
    });

    var existingPages;
    var newPage;
    var newPageIndex;

    existingPages = $(settings.target + ' :data(page-index)');

    if (settings.clearHistory) {
      newPageIndex = 1;
    } else {
      newPageIndex = existingPages.length + 1;
    }

    if (settings.clearHistory) {
      $(settings.target + ' :data(page-index)').not('.a-current-page').remove();
    }

    newPage = $('<div/>', {
      class: 'a-page a-next-page',
      data: {
        pageIndex: newPageIndex,
        isSuccess: settings.isSuccess,
        isError: settings.isError,
        showModalNav: settings.showModalNav
      },
      html: modalPage
    });

    // if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {
    //   goToModalHeader();
    // }

    $(settings.target + ' .a-modal-content-target').append(newPage);

    $(settings.target).animate({
      scrollTop: 0
    }, 20);

    current = $(settings.target + ' .a-current-page');

    setTimeout(function() {
      $('body').removeClass('a-modal-background-error a-displayNav');
      $('body').removeClass('a-modal-background-success');

      current.removeClass('a-current-page').addClass('a-previous-page');
      newPage.removeClass('a-next-page').addClass('a-current-page');
      $(newPage).data().enableDirtyPopover = settings.enableDirtyPopover;

      if (settings.isError) {
        $('body').addClass('a-modal-background-error');
        if (settings.showModalNav) {
          $('body').addClass('a-displayNav');
        }
      } else if (settings.isSuccess) {
        $('body').addClass('a-modal-background-success');
      }
    }, 0);

    current.on('transitionend', function() {
      if (settings.clearHistory) {
        $(settings.target + ' :data(page-index)').not('.a-current-page').remove();
      } else {
        current.hide().off();
      }
    });

    popoverLocalInit();
  },

  nextModalPage: function(settings) {
    var currentRequest = $.ajax({
      url: settings.url,
      beforeSend: function() {
        if (typeof currentRequest !== 'undefined') {
          currentRequest.abort();
        }
        AltinnLoader.addLoader($(settings.target).find('.a-current-page .a-modal-body'));
      },
      data: settings.data
    }).always(function() {
    }).done(function(data) {
      var current;
      var modalPage = $('<div/>', {
        class: 'modalPage',
        html: data
      });

      var existingPages;
      var newPage;
      var newPageIndex;

      existingPages = $(settings.target + ' :data(page-index)');

      if (settings.clearHistory) {
        newPageIndex = 1;
      } else {
        newPageIndex = existingPages.length + 1;
      }

      if (settings.clearHistory) {
        $(settings.target + ' :data(page-index)').not('.a-current-page').remove();
      }

      newPage = $('<div/>', {
        class: 'a-page a-next-page',
        data: {
          pageIndex: newPageIndex,
          isSuccess: settings.isSuccess,
          isError: settings.isError,
          showModalNav: settings.showModalNav
        },
        html: modalPage
      });

      // if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {
      //   goToModalHeader();
      // }

      $(settings.target + ' .a-modal-content-target').append(newPage);

      $(settings.target).animate({
        scrollTop: 0
      }, 20);

      current = $(settings.target + ' .a-current-page');

      setTimeout(function() {
        $('body').removeClass('a-modal-background-error a-displayNav');
        $('body').removeClass('a-modal-background-success');

        current.removeClass('a-current-page').addClass('a-previous-page');
        newPage.removeClass('a-next-page').addClass('a-current-page');
        $(newPage).data().enableDirtyPopover = settings.enableDirtyPopover;

        if (settings.isError) {
          $('body').addClass('a-modal-background-error');
          if (settings.showModalNav) {
            $('body').addClass('a-displayNav');
          }
        } else if (settings.isSuccess) {
          $('body').addClass('a-modal-background-success');
        }
      }, 0);

      current.on('transitionend', function() {
        if (settings.clearHistory) {
          $(settings.target + ' :data(page-index)').not('.a-current-page').remove();
        } else {
          current.hide().off();
        }

        AltinnLoader.removeLoader(current.find('.a-modal-body'));
      });

      popoverLocalInit();
    });
  },

  previousModalPage: function(settings) {
    var current;
    var allPages;
    var previous;
    var pagesToPop;
    var isError;
    var showModalNav;
    var isSuccess;

    if (!settings.pagesToPop) {
      pagesToPop = 1;
    } else {
      pagesToPop = settings.pagesToPop;
    }

    if ($(settings.target + ' .a-current-page').data('page-index') - pagesToPop <= 0) {
      $(settings.target).one('hidden.bs.modal', function() {
        $('body').removeClass('a-modal-background-error a-displayNav');
        $('body').removeClass('a-modal-background-success');
      });

      $(settings.target).modal('hide');
      return;
    }

    current = $(settings.target + ' .a-current-page');
    allPages = $(settings.target + ' :data(page-index)');
    previous = allPages.filter(function() {
      return $(this).data('page-index') === allPages.length - 1;
    });

    previous.show();
    isError = $(previous).data().isError;
    showModalNav = $(previous).data().showModalNav;
    isSuccess = $(previous).data().isSuccess;

    current.addClass('a-next-page');
    current.removeClass('a-current-page');

    // if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {
    //   goToModalHeader();
    // }

    setTimeout(function() {
      $('body').removeClass('a-modal-background-error a-displayNav');
      $('body').removeClass('a-modal-background-success');

      previous.addClass('a-current-page').removeClass('a-previous-page');

      if (isError) {
        $('body').addClass('a-modal-background-error');
        if (showModalNav) {
          $('body').addClass('a-displayNav');
        }
      } else if (isSuccess) {
        $('body').addClass('a-modal-background-success');
      }
    }, 0);

    current.on('transitionend', function() {
      var previousPages = allPages.filter(function() {
        return $(this).data('page-index') > allPages.length - pagesToPop;
      });
      previousPages.remove();
    });
  },

  setCurrentPageIsDirty: function(target, state) {
    $(target).find('.a-current-page').first().data().isDirty = state;
  },

  init: function() {
    var that = this;
    $('body').on('click', '[data-toggle="altinn-modal"]', function() {
      var $source = $(this);
      if ($source.data().action === 'load') {
        that.loadModal({
          url: $source.data().url,
          target: $source.data().target,
          enableDirtyPopover: $source.data().enableDirtyPopover
        });
      } else if ($source.data().action === 'next') {
        that.nextModalPage({ url: $source.data().url,
          target: $source.data().target,
          isSuccess: $source.data().isSuccess,
          isError: $source.data().isError,
          showModalNav: $source.data().showModalNav,
          clearHistory: $source.data().clearHistory,
          enableDirtyPopover: $source.data().enableDirtyPopover });
      } else if ($source.data().action === 'back') {
        that.previousModalPage({
          target: $source.data().target,
          pagesToPop: $source.data().pages
        });
      } else if ($source.data().action === 'close') {
        that.closeModal({ target: $source.data().target });
      }
    });

    $('body').on('click', '.a-modal-back', function() {
      var $modal = $(this).closest('.a-modal');
      if ($modal.find('.a-current-page').first().data().enableDirtyPopover
        && $modal.find('.a-current-page').first().data().isDirty) {
        $(this).popover('show');
      } else {
        that.previousModalPage({ target: '#' + $modal[0].id });
      }
    });

    $('body').on('click', '.a-modal-close', function() {
      var $modal = $(this).closest('.a-modal');
      if ($modal.find('.a-current-page').first().data().enableDirtyPopover
        && $modal.find('.a-current-page').first().data().isDirty) {
        $(this).popover('show');
      } else {
        that.closeModal({ target: '#' + $modal[0].id });
      }
    });

    $('body').on('click', '.a-js-modal-dirtyBackBtn', function() {
      AltinnModal.previousModalPage({ target: '#' + $(this).closest('.a-modal')[0].id });
      $('button[aria-describedby=' + $(this).parent().parent().attr('id') + ']').popover('hide');
    });

    $('body').on('click', '.a-js-modal-dirtyCancelBtn', function() {
      $('button[aria-describedby=' + $(this).parent().parent().attr('id') + ']').popover('hide');
    });

    $('body').on('click', '.a-js-modal-dirtyCloseBtn', function() {
      AltinnModal.closeModal({ target: '#' + $(this).closest('.a-modal')[0].id });
      $('button[aria-describedby=' + $(this).parent().parent().attr('id') + ']').popover('hide');
    });

    function urlQuery(query) { // Parse current URL for query value
      var _query = query.replace(/[[]/, '[').replace(/[\]]/, '\\]');
      var expr = '[\\?&]' + _query + '=([^&#]*)';
      var regex = new RegExp(expr);
      var results = regex.exec(window.location.href);
      if (results !== null) {
        return results[1];
      }
      return false;
    }
    if (urlQuery('form') === '1') {
      AltinnModal.loadModal({
        url: '/hjelp/kontaktskjema-for-hjelp/',
        target: '#modal'
      });
    }
  }
};
<commit_msg>added functionality to change display property of footer inside modal<commit_after>/* globals currentRequest, popoverLocalInit, AltinnModal */
/* globals AltinnModal:true, AltinnLoader */
AltinnModal = {
  closeModal: function(settings) {
    $('body').removeClass('a-modal-background-error a-displayNav');
    $('body').removeClass('a-modal-background-success');
    $(settings.target).modal('hide');
    $('body').append($('.a-stickyHelp-container'));
  },

  loadModal: function(settings) {
    var currentRequest = $.ajax({
      url: settings.url,
      beforeSend: function() {
        if (typeof currentRequest !== 'undefined') {
          currentRequest.abort();
        }

        AltinnLoader.addLoader($('body'));
      },
      data: settings.data
    }).always(function() {
    }).done(function(data) {
      var modalPage = $('<div/>', {
        class: 'modalPage',
        html: data
      });
      var page = $('<div/>', {
        class: 'a-page a-current-page',
        data: {
          pageIndex: 1,
          isSuccess: settings.isSuccess,
          isError: settings.isError,
          showModalNav: settings.showModalNav
        },
        html: modalPage
      });

      $('body').removeClass('a-modal-background-error a-displayNav');
      $('body').removeClass('a-modal-background-success');

      // if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {
      //   goToModalHeader();
      // }

      $(settings.target + ' .a-modal-content-target').append(page);
      $(settings.target).find('.a-current-page').first().data().enableDirtyPopover = settings.enableDirtyPopover;

      // Initialize with backdrop: static to prevent modal from closing when clicking outside,
      // and keyboard: false to prevent ESC from closing the modal
      $(settings.target).modal({
        backdrop: 'static',
        keyboard: false
      });

      $(settings.target).on('hidden.bs.modal', function() {
        $(settings.target + ' .a-modal-content-target').empty();
        $(settings.target).attr('aria-hidden', true);
        $('.a-containerFooter').removeClass('d-none');
      });

      $(settings.target).on('shown.bs.modal', function() {
        $(settings.target).removeAttr('aria-hidden');
        $('.a-containerFooter').addClass('d-none');
      });
      popoverLocalInit();

      if (settings.isError) {
        $('body').addClass('a-modal-background-error');
        if (settings.showModalNav) {
          $('body').addClass('a-displayNav');
        }
      } else if (settings.isSuccess) {
        $('body').addClass('a-modal-background-success');
      }

      AltinnLoader.removeLoader($('body'));
      $(settings.target).on('transitionend', function() {
        $(settings.target).append($('.a-stickyHelp-container'));
      });
    });
  },

  nextModalPageWithContent: function(settings) {
    var current;
    var modalPage = $('<div/>', {
      class: 'modalPage',
      html: settings.content
    });

    var existingPages;
    var newPage;
    var newPageIndex;

    existingPages = $(settings.target + ' :data(page-index)');

    if (settings.clearHistory) {
      newPageIndex = 1;
    } else {
      newPageIndex = existingPages.length + 1;
    }

    if (settings.clearHistory) {
      $(settings.target + ' :data(page-index)').not('.a-current-page').remove();
    }

    newPage = $('<div/>', {
      class: 'a-page a-next-page',
      data: {
        pageIndex: newPageIndex,
        isSuccess: settings.isSuccess,
        isError: settings.isError,
        showModalNav: settings.showModalNav
      },
      html: modalPage
    });

    // if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {
    //   goToModalHeader();
    // }

    $(settings.target + ' .a-modal-content-target').append(newPage);

    $(settings.target).animate({
      scrollTop: 0
    }, 20);

    current = $(settings.target + ' .a-current-page');

    setTimeout(function() {
      $('body').removeClass('a-modal-background-error a-displayNav');
      $('body').removeClass('a-modal-background-success');

      current.removeClass('a-current-page').addClass('a-previous-page');
      newPage.removeClass('a-next-page').addClass('a-current-page');
      $(newPage).data().enableDirtyPopover = settings.enableDirtyPopover;

      if (settings.isError) {
        $('body').addClass('a-modal-background-error');
        if (settings.showModalNav) {
          $('body').addClass('a-displayNav');
        }
      } else if (settings.isSuccess) {
        $('body').addClass('a-modal-background-success');
      }
    }, 0);

    current.on('transitionend', function() {
      if (settings.clearHistory) {
        $(settings.target + ' :data(page-index)').not('.a-current-page').remove();
      } else {
        current.hide().off();
      }
    });

    popoverLocalInit();
  },

  nextModalPage: function(settings) {
    var currentRequest = $.ajax({
      url: settings.url,
      beforeSend: function() {
        if (typeof currentRequest !== 'undefined') {
          currentRequest.abort();
        }
        AltinnLoader.addLoader($(settings.target).find('.a-current-page .a-modal-body'));
      },
      data: settings.data
    }).always(function() {
    }).done(function(data) {
      var current;
      var modalPage = $('<div/>', {
        class: 'modalPage',
        html: data
      });

      var existingPages;
      var newPage;
      var newPageIndex;

      existingPages = $(settings.target + ' :data(page-index)');

      if (settings.clearHistory) {
        newPageIndex = 1;
      } else {
        newPageIndex = existingPages.length + 1;
      }

      if (settings.clearHistory) {
        $(settings.target + ' :data(page-index)').not('.a-current-page').remove();
      }

      newPage = $('<div/>', {
        class: 'a-page a-next-page',
        data: {
          pageIndex: newPageIndex,
          isSuccess: settings.isSuccess,
          isError: settings.isError,
          showModalNav: settings.showModalNav
        },
        html: modalPage
      });

      // if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {
      //   goToModalHeader();
      // }

      $(settings.target + ' .a-modal-content-target').append(newPage);

      $(settings.target).animate({
        scrollTop: 0
      }, 20);

      current = $(settings.target + ' .a-current-page');

      setTimeout(function() {
        $('body').removeClass('a-modal-background-error a-displayNav');
        $('body').removeClass('a-modal-background-success');

        current.removeClass('a-current-page').addClass('a-previous-page');
        newPage.removeClass('a-next-page').addClass('a-current-page');
        $(newPage).data().enableDirtyPopover = settings.enableDirtyPopover;

        if (settings.isError) {
          $('body').addClass('a-modal-background-error');
          if (settings.showModalNav) {
            $('body').addClass('a-displayNav');
          }
        } else if (settings.isSuccess) {
          $('body').addClass('a-modal-background-success');
        }
      }, 0);

      current.on('transitionend', function() {
        if (settings.clearHistory) {
          $(settings.target + ' :data(page-index)').not('.a-current-page').remove();
        } else {
          current.hide().off();
        }

        AltinnLoader.removeLoader(current.find('.a-modal-body'));
      });

      popoverLocalInit();
    });
  },

  previousModalPage: function(settings) {
    var current;
    var allPages;
    var previous;
    var pagesToPop;
    var isError;
    var showModalNav;
    var isSuccess;

    if (!settings.pagesToPop) {
      pagesToPop = 1;
    } else {
      pagesToPop = settings.pagesToPop;
    }

    if ($(settings.target + ' .a-current-page').data('page-index') - pagesToPop <= 0) {
      $(settings.target).one('hidden.bs.modal', function() {
        $('body').removeClass('a-modal-background-error a-displayNav');
        $('body').removeClass('a-modal-background-success');
      });

      $(settings.target).modal('hide');
      return;
    }

    current = $(settings.target + ' .a-current-page');
    allPages = $(settings.target + ' :data(page-index)');
    previous = allPages.filter(function() {
      return $(this).data('page-index') === allPages.length - 1;
    });

    previous.show();
    isError = $(previous).data().isError;
    showModalNav = $(previous).data().showModalNav;
    isSuccess = $(previous).data().isSuccess;

    current.addClass('a-next-page');
    current.removeClass('a-current-page');

    // if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {
    //   goToModalHeader();
    // }

    setTimeout(function() {
      $('body').removeClass('a-modal-background-error a-displayNav');
      $('body').removeClass('a-modal-background-success');

      previous.addClass('a-current-page').removeClass('a-previous-page');

      if (isError) {
        $('body').addClass('a-modal-background-error');
        if (showModalNav) {
          $('body').addClass('a-displayNav');
        }
      } else if (isSuccess) {
        $('body').addClass('a-modal-background-success');
      }
    }, 0);

    current.on('transitionend', function() {
      var previousPages = allPages.filter(function() {
        return $(this).data('page-index') > allPages.length - pagesToPop;
      });
      previousPages.remove();
    });
  },

  setCurrentPageIsDirty: function(target, state) {
    $(target).find('.a-current-page').first().data().isDirty = state;
  },

  init: function() {
    var that = this;
    $('body').on('click', '[data-toggle="altinn-modal"]', function() {
      var $source = $(this);
      if ($source.data().action === 'load') {
        that.loadModal({
          url: $source.data().url,
          target: $source.data().target,
          enableDirtyPopover: $source.data().enableDirtyPopover
        });
      } else if ($source.data().action === 'next') {
        that.nextModalPage({ url: $source.data().url,
          target: $source.data().target,
          isSuccess: $source.data().isSuccess,
          isError: $source.data().isError,
          showModalNav: $source.data().showModalNav,
          clearHistory: $source.data().clearHistory,
          enableDirtyPopover: $source.data().enableDirtyPopover });
      } else if ($source.data().action === 'back') {
        that.previousModalPage({
          target: $source.data().target,
          pagesToPop: $source.data().pages
        });
      } else if ($source.data().action === 'close') {
        that.closeModal({ target: $source.data().target });
      }
    });

    $('body').on('click', '.a-modal-back', function() {
      var $modal = $(this).closest('.a-modal');
      if ($modal.find('.a-current-page').first().data().enableDirtyPopover
        && $modal.find('.a-current-page').first().data().isDirty) {
        $(this).popover('show');
      } else {
        that.previousModalPage({ target: '#' + $modal[0].id });
      }
    });

    $('body').on('click', '.a-modal-close', function() {
      var $modal = $(this).closest('.a-modal');
      if ($modal.find('.a-current-page').first().data().enableDirtyPopover
        && $modal.find('.a-current-page').first().data().isDirty) {
        $(this).popover('show');
      } else {
        that.closeModal({ target: '#' + $modal[0].id });
      }
    });

    $('body').on('click', '.a-js-modal-dirtyBackBtn', function() {
      AltinnModal.previousModalPage({ target: '#' + $(this).closest('.a-modal')[0].id });
      $('button[aria-describedby=' + $(this).parent().parent().attr('id') + ']').popover('hide');
    });

    $('body').on('click', '.a-js-modal-dirtyCancelBtn', function() {
      $('button[aria-describedby=' + $(this).parent().parent().attr('id') + ']').popover('hide');
    });

    $('body').on('click', '.a-js-modal-dirtyCloseBtn', function() {
      AltinnModal.closeModal({ target: '#' + $(this).closest('.a-modal')[0].id });
      $('button[aria-describedby=' + $(this).parent().parent().attr('id') + ']').popover('hide');
    });

    function urlQuery(query) { // Parse current URL for query value
      var _query = query.replace(/[[]/, '[').replace(/[\]]/, '\\]');
      var expr = '[\\?&]' + _query + '=([^&#]*)';
      var regex = new RegExp(expr);
      var results = regex.exec(window.location.href);
      if (results !== null) {
        return results[1];
      }
      return false;
    }
    if (urlQuery('form') === '1') {
      AltinnModal.loadModal({
        url: '/hjelp/kontaktskjema-for-hjelp/',
        target: '#modal'
      });
    }
  }
};
<|endoftext|>


<commit_before>'use strict';
/* global require, console, Buffer */
var streamy = require('streamy-data'),
	pesticide = require('./bin/pesticide'),
	gulp = require('gulp'),
	File = require('vinyl'),
	fs = require('fs');

gulp.task('data.download', [
	'data.download.pesticide'
]);

/* This task shall write the following files:
 * + /_raw/download/licenses.json
 * + /_raw/download/index.json
 * + /_raw/download/entries/{id}.json
 */
/* jshint asi: true */
gulp.task('data.download.pesticide', function (callback) {

	// TODO: clear

	// callback is invoked when end is called three times
	var end = streamy.util.wait(3, callback);

	// grab index json data from the website
	pesticide.download.licenses(function (licenses) {

		console.log('license file downloaded.');

		// TODO: use mkdirp or writefile

		// write licenses file
		fs.writeFile('./_raw/download/pesticide/licenses.json',
			JSON.stringify(licenses, null, '\t'), end); // end 1

		/* Write index file. We could have deferred this part to
		 * building phase, but this will make everything easier.
		 */
		var index = pesticide.build.indexFromLicenses(licenses);
		fs.writeFile('./_raw/download/pesticide/index.json',
			JSON.stringify(index, null, '\t'), end); // end 2

		// transform the index list into an object stream
		var ids = index.map(function (data) { return data.id });
		streamy.array(ids)
			// transform them into detailed data object from the website
			.pipe(streamy.map(pesticide.download.entry))
			// transform them into vinyl file format (to work with gulp.dest)
			.pipe(streamy.file.vinylify(function (data) {
				return './' + data.id + '.json';
			}, {
				stringify: { space: '\t' }
			}))
			// write file to specified destination
			.pipe(gulp.dest('./_raw/download/pesticide/entries'))
			.on('data', function () {})
			.on('end', end); // end 3
	});

});

/* In hopes of manually calling download tasks, we keep build tasks away from
 * dependencies to them.
 */
gulp.task('data.build', [
	'data.build.pesticide',
	'data.build.formulation'
]);

/* Precondition: all downloaded raw files are available, which includes:
 * + /_raw/download/pesticide/licenses.json
 * + /_raw/download/pesticide/index.json
 * + /_raw/download/pesticide/entries/{id}.json
 *
 * This task shall write the following files:
 * + /_data/pesticide/list.json
 * + /_data/pesticide/entries/{id}.json
 * + /pesticide/entries/{id}.html
 * + /data/pesticide/usages-search.json
 */
gulp.task('data.build.pesticide', function (callback) {

	// callback is invoked when end is called three times
	var end = streamy.util.wait(4, callback);

	fs.readFile('./_raw/download/pesticide/index.json', 'utf8', function (err, data) {

		var index = JSON.parse(data),
			m = {};

		fs.writeFile('./_data/pesticide/list.json', data, end); // end 1

		streamy.array(index.slice(0)) // TODO: stream array bug
			.pipe(streamy.map.sync(function (data) {
				return new File({
					path: './' + data.id + '.html',
					contents: new Buffer('---\nlayout: pesticide-entry\nid: ' + data.id + '\n---\n')
				});
			}))
			.pipe(gulp.dest('./pesticide/entries'))
			.on('data', function () {})
			.on('end', end); // end 2

		// initialize entry objects
		index.forEach(function (entry) {
			entry.licenses = [];
			m[entry.id] = entry;
		});

		fs.readFile('./_raw/download/pesticide/licenses.json', 'utf8', function (err, data) {

			var licenses = JSON.parse(data),
				usageSearchData = {},
				usages = usageSearchData.usages = [],
				pesticideMap = usageSearchData.pesticides = {},
				id, entry;

			usageSearchData.corpMap = {};

			// TODO: move these to bin/util
			var clone = function (tar, src) {
				if (!src) {
					src = tar;
					tar = {};
				}
				Object.keys(src).forEach(function (k) {
					tar[k] = src[k];
				});
				return tar;
			};

			var copyIfAbsent = function (tar, src, field) {
				var vo = tar[field],
					vn = src[field];
				if (!vo)
					tar[field] = vn;
				else if (vo != vn)
					console.log('Conflict field values: \n' + vo + ', \n' + vn);
			};

			// include information from license data
			licenses.forEach(function (lic) {
				id = lic['農藥代號'];
				entry = m[id];

				copyIfAbsent(entry, lic, '英文名稱');
				// the composition ratio might be different per license
				//copyIfAbsent(entry, lic, '化學成分');

				entry.licenses.push({
					'許可證號': lic['許可證號'],
					'化學成分': lic['化學成分'],
					'廠牌名稱': lic['廠牌名稱'],
					'國外原製造廠商': lic['國外原製造廠商'],
					'有效期限': lic['有效期限'],
					'廠商名稱': lic['廠商名稱']
				});

			});

			// collect pesticide search: pesticide entries
			index.forEach(function (entry) {
				var products = {};
				entry.licenses.forEach(function (lic) {
					if (lic['廠牌名稱'])
						products[lic['廠牌名稱']] = 1;
				});
				pesticideMap[entry.id] = {
					id: entry.id,
					name: entry.name || '',
					engName: entry['英文名稱'] || '',
					products: Object.keys(products).join('#')
				};
			});

			// include information from entry files
			gulp.src(['./_raw/download/pesticide/entries/*'])
				.pipe(streamy.file.unvinylify())
				.on('data', function (data) {
					// merge into pesticide entries
					var entry = m[data.id];
					copyIfAbsent(entry, data, '廠牌名稱');
					copyIfAbsent(entry, data, '通過日期');
					entry.usages = data.usages;

					// collect pesticide search: usage entries
					data.usages.forEach(function (u) {
						usages.push(clone({ pesticideId: data.id }, u));
					});
				})
				.on('end', function () {

					// write usages-search.json
					fs.writeFile('./data/pesticide/usages-search.json',
						JSON.stringify(usageSearchData, null, '\t'), end); // end 3

					// TODO: write to _data/pestcide/entries/[id].json, replace gulp.dest('./pesticide')

					// write pesticide entry pages
					streamy.array(index)
						.pipe(streamy.map.sync(function (data) {
							return new File({
								path: './' + data.id + '.json',
								contents: new Buffer(JSON.stringify(data, null, '\t'))
							});
						}))
						.pipe(gulp.dest('./_data/pesticide/entries'))
						.on('data', function () {})
						.on('end', end); // end 4
				});

		});

	});

});

/* Precondition: the following files are available:
 * + /_raw/manual/pesticide/fomulations.json
 *
 * This task shall write the following files:
 * + /_data/pesticide/formulations.json
 * + /data/pesticide/formulations.json
 */
gulp.task('data.build.formulations', function (callback) {

	// callback is invoked when end is called 2 times
	var end = streamy.util.wait(2, callback);

	fs.readFile('./_raw/manual/pesticide/formulations.json', 'utf8', function (err, data) {
		fs.writeFile('./_data/pesticide/formulations.json', data, end); // end 1
		fs.writeFile('./data/pesticide/formulations.json', data, end); // end 2
	});

});
<commit_msg>fix task: data.build<commit_after>'use strict';
/* global require, console, Buffer */
var streamy = require('streamy-data'),
	pesticide = require('./bin/pesticide'),
	gulp = require('gulp'),
	File = require('vinyl'),
	fs = require('fs');

gulp.task('data.download', [
	'data.download.pesticide'
]);

/* This task shall write the following files:
 * + /_raw/download/licenses.json
 * + /_raw/download/index.json
 * + /_raw/download/entries/{id}.json
 */
/* jshint asi: true */
gulp.task('data.download.pesticide', function (callback) {

	// TODO: clear

	// callback is invoked when end is called three times
	var end = streamy.util.wait(3, callback);

	// grab index json data from the website
	pesticide.download.licenses(function (licenses) {

		console.log('license file downloaded.');

		// TODO: use mkdirp or writefile

		// write licenses file
		fs.writeFile('./_raw/download/pesticide/licenses.json',
			JSON.stringify(licenses, null, '\t'), end); // end 1

		/* Write index file. We could have deferred this part to
		 * building phase, but this will make everything easier.
		 */
		var index = pesticide.build.indexFromLicenses(licenses);
		fs.writeFile('./_raw/download/pesticide/index.json',
			JSON.stringify(index, null, '\t'), end); // end 2

		// transform the index list into an object stream
		var ids = index.map(function (data) { return data.id });
		streamy.array(ids)
			// transform them into detailed data object from the website
			.pipe(streamy.map(pesticide.download.entry))
			// transform them into vinyl file format (to work with gulp.dest)
			.pipe(streamy.file.vinylify(function (data) {
				return './' + data.id + '.json';
			}, {
				stringify: { space: '\t' }
			}))
			// write file to specified destination
			.pipe(gulp.dest('./_raw/download/pesticide/entries'))
			.on('data', function () {})
			.on('end', end); // end 3
	});

});

/* In hopes of manually calling download tasks, we keep build tasks away from
 * dependencies to them.
 */
gulp.task('data.build', [
	'data.build.pesticide',
	'data.build.formulations'
]);

/* Precondition: all downloaded raw files are available, which includes:
 * + /_raw/download/pesticide/licenses.json
 * + /_raw/download/pesticide/index.json
 * + /_raw/download/pesticide/entries/{id}.json
 *
 * This task shall write the following files:
 * + /_data/pesticide/list.json
 * + /_data/pesticide/entries/{id}.json
 * + /pesticide/entries/{id}.html
 * + /data/pesticide/usages-search.json
 */
gulp.task('data.build.pesticide', function (callback) {

	// callback is invoked when end is called three times
	var end = streamy.util.wait(4, callback);

	fs.readFile('./_raw/download/pesticide/index.json', 'utf8', function (err, data) {

		var index = JSON.parse(data),
			m = {};

		fs.writeFile('./_data/pesticide/list.json', data, end); // end 1

		streamy.array(index.slice(0)) // TODO: stream array bug
			.pipe(streamy.map.sync(function (data) {
				return new File({
					path: './' + data.id + '.html',
					contents: new Buffer('---\nlayout: pesticide-entry\nid: ' + data.id + '\n---\n')
				});
			}))
			.pipe(gulp.dest('./pesticide/entries'))
			.on('data', function () {})
			.on('end', end); // end 2

		// initialize entry objects
		index.forEach(function (entry) {
			entry.licenses = [];
			m[entry.id] = entry;
		});

		fs.readFile('./_raw/download/pesticide/licenses.json', 'utf8', function (err, data) {

			var licenses = JSON.parse(data),
				usageSearchData = {},
				usages = usageSearchData.usages = [],
				pesticideMap = usageSearchData.pesticides = {},
				id, entry;

			usageSearchData.corpMap = {};

			// TODO: move these to bin/util
			var clone = function (tar, src) {
				if (!src) {
					src = tar;
					tar = {};
				}
				Object.keys(src).forEach(function (k) {
					tar[k] = src[k];
				});
				return tar;
			};

			var copyIfAbsent = function (tar, src, field) {
				var vo, vn;
				if (tar === undefined)
					throw new Error('Target is missing: ' + field);
				if (src === undefined)
					throw new Error('Source is missing: ' + field);
				vo = tar[field];
				vn = src[field];
				if (!vo)
					tar[field] = vn;
				else if (vo != vn)
					console.log('Conflict field values: \n' + vo + ', \n' + vn);
			};

			// include information from license data
			licenses.forEach(function (lic) {
				id = lic['農藥代號'];
				entry = m[id];

				copyIfAbsent(entry, lic, '英文名稱');
				// the composition ratio might be different per license
				//copyIfAbsent(entry, lic, '化學成分');

				entry.licenses.push({
					'許可證號': lic['許可證號'],
					'化學成分': lic['化學成分'],
					'廠牌名稱': lic['廠牌名稱'],
					'國外原製造廠商': lic['國外原製造廠商'],
					'有效期限': lic['有效期限'],
					'廠商名稱': lic['廠商名稱']
				});

			});

			// collect pesticide search: pesticide entries
			index.forEach(function (entry) {
				var products = {};
				entry.licenses.forEach(function (lic) {
					if (lic['廠牌名稱'])
						products[lic['廠牌名稱']] = 1;
				});
				pesticideMap[entry.id] = {
					id: entry.id,
					name: entry.name || '',
					engName: entry['英文名稱'] || '',
					products: Object.keys(products).join('#')
				};
			});

			// include information from entry files
			gulp.src(['./_raw/download/pesticide/entries/*'])
				.pipe(streamy.file.unvinylify())
				.on('data', function (data) {
					// merge into pesticide entries
					var entry = m[data.id];
					if (entry === undefined) {
						console.warn(
							'Should update',
							'`./_raw/download/pesticide/index.json`',
							'for ' + data.id + '.'
						);
						entry = data
					} else {
						copyIfAbsent(entry, data, '廠牌名稱');
						copyIfAbsent(entry, data, '通過日期');
						copyIfAbsent(entry, data, 'usages');
					}

					// collect pesticide search: usage entries
					data.usages.forEach(function (u) {
						usages.push(clone({ pesticideId: data.id }, u));
					});
				})
				.on('end', function () {

					// write usages-search.json
					fs.writeFile('./data/pesticide/usages-search.json',
						JSON.stringify(usageSearchData, null, '\t'), end); // end 3

					// TODO: write to _data/pestcide/entries/[id].json, replace gulp.dest('./pesticide')

					// write pesticide entry pages
					streamy.array(index)
						.pipe(streamy.map.sync(function (data) {
							return new File({
								path: './' + data.id + '.json',
								contents: new Buffer(JSON.stringify(data, null, '\t'))
							});
						}))
						.pipe(gulp.dest('./_data/pesticide/entries'))
						.on('data', function () {})
						.on('end', end); // end 4
				});

		});

	});

});

/* Precondition: the following files are available:
 * + /_raw/manual/pesticide/fomulations.json
 *
 * This task shall write the following files:
 * + /_data/pesticide/formulations.json
 * + /data/pesticide/formulations.json
 */
gulp.task('data.build.formulations', function (callback) {

	// callback is invoked when end is called 2 times
	var end = streamy.util.wait(2, callback);

	fs.readFile('./_raw/manual/pesticide/formulations.json', 'utf8', function (err, data) {
		fs.writeFile('./_data/pesticide/formulations.json', data, end); // end 1
		fs.writeFile('./data/pesticide/formulations.json', data, end); // end 2
	});

});
<|endoftext|>


<commit_before>var emberize = function(object) {
    for (var i in object) {
        if (object.hasOwnProperty(i)) {
            if (Ember.typeOf(object[i]) == 'object') {
                object[i] = emberize(object[i]);
            }
        }
    }
    return Em.Object.create(object);
};

Ember.Model.reopenClass({

	makeLoadableProp : function(propName, restFunc, transformFunc) {
		var fakePropname = '_'+propName;

		var f = function(key, value) {
			if (arguments.length == 2) {
				this.set(fakePropname, value);
				return value;
			} else {
				if (typeof(this.get(fakePropname))=='undefined') {
					var that = this;
					this.callRestOnObject(restFunc).then(function(res) {
						if (transformFunc) {
							res = transformFunc(res);
						} else if (res && typeof res == 'object') {
							res = emberize(res);
						}
						that.set(fakePropname, res);
						that.notifyPropertyChange(propName);
					});
				}
				return this.get(fakePropname);
			}
		}.property();

		return f;
	},

	makeLoadableArrayProp : function(propName, restFunc, transformFunc) {
		var fakePropname = '_'+propName;
		return function(key, value) {
			if (arguments.length == 1 || arguments[1] == ({}[1])) {
				if (typeof(this.get(fakePropname))=='undefined' || (arguments.length == 2 && arguments[1] == ({}[1])) ) {
					this.set(fakePropname, []);
					var that = this;
					this.callRestOnObject(restFunc).then(function(data) {
						var d = [];
						if (transformFunc) {
							for (var i in data) {
								d.push(transformFunc(i, data[i]));
							}
						} else {
							d = data;
						}
						data = d.sort(function(a, b) {
							return a.id - b.id;
						});

						data.forEach(function(item) {
							that.get(fakePropname).addObject(item);
						});
					});
				}
				return this.get(fakePropname);
			} else {
				this.set(fakePropname, value);
				return value;
			}

		}.property(fakePropname+'.@each');
	}

});
<commit_msg>BUG: fetching property on unsaved model object<commit_after>var emberize = function(object) {
    for (var i in object) {
        if (object.hasOwnProperty(i)) {
            if (Ember.typeOf(object[i]) == 'object') {
                object[i] = emberize(object[i]);
            }
        }
    }
    return Em.Object.create(object);
};

Ember.Model.reopenClass({

	makeLoadableProp : function(propName, restFunc, transformFunc) {
		var fakePropname = '_'+propName;

		var f = function(key, value) {
			if (arguments.length == 2) {
				this.set(fakePropname, value);
				return value;
			} else {
				if (typeof this.get(Em.get(this.constructor,'primaryKey')) === "undefined") {
					return undefined;
				}

				if (typeof(this.get(fakePropname))=='undefined') {
					var that = this;
					this.callRestOnObject(restFunc).then(function(res) {
						if (transformFunc) {
							res = transformFunc(res);
						} else if (res && typeof res == 'object') {
							res = emberize(res);
						}
						that.set(fakePropname, res);
						that.notifyPropertyChange(propName);
					});
				}
				return this.get(fakePropname);
			}
		}.property();

		return f;
	},

	makeLoadableArrayProp : function(propName, restFunc, transformFunc) {
		var fakePropname = '_'+propName;
		return function(key, value) {
			if (arguments.length == 1 || arguments[1] == ({}[1])) {
				if (typeof(this.get(fakePropname))=='undefined' || (arguments.length == 2 && arguments[1] == ({}[1])) ) {
					this.set(fakePropname, []);
					var that = this;
					this.callRestOnObject(restFunc).then(function(data) {
						var d = [];
						if (transformFunc) {
							for (var i in data) {
								d.push(transformFunc(i, data[i]));
							}
						} else {
							d = data;
						}
						data = d.sort(function(a, b) {
							return a.id - b.id;
						});

						data.forEach(function(item) {
							that.get(fakePropname).addObject(item);
						});
					});
				}
				return this.get(fakePropname);
			} else {
				this.set(fakePropname, value);
				return value;
			}

		}.property(fakePropname+'.@each');
	}

});
<|endoftext|>


<commit_before>// Source: http://stackoverflow.com/a/1830844
function isNumber(n) {
  return !isNaN(parseFloat(n)) && isFinite(n);
}

function statBonus(statValue) {
    if(!isNumber(statValue)) {
        return false;
    }
    switch(+statValue) { // cast to number
        case 0:
            return "–";
            break;
        case 1:
            return -5;
            break;
        case 2:
            return -3;
            break;
        case 3:
            return 0;
            break;
        case 4:
            return 1;
            break;
        case 5:
            return 3;
            break;
        case 6:
            return 5;
            break;
        case 7:
            return 9;
            break;
        case 8:
            return 15;
            break;
        case 9:
            return 21;
            break;
        default:
            return false;
    }
}

function AppViewModel() {
    this.statStrength = ko.observable();
    this.statEndurance = ko.observable();
    this.statAgility = ko.observable();
    this.statSpeed = ko.observable();

    this.statWillpower = ko.observable();
    this.statInsight = ko.observable();
    this.statReasoning = ko.observable();
    this.statPerception = ko.observable();

    this.statPresence = ko.observable();
    this.statComposure = ko.observable();
    this.statManipulation = ko.observable();
    this.statBeauty = ko.observable();

    this.statBonusStrength = ko.computed(function() {
        return statBonus(this.statStrength());
    }, this);
}

// Activate knockout.js
ko.applyBindings(new AppViewModel());
<commit_msg>Add array of groups of character attributes.<commit_after>// Source: http://stackoverflow.com/a/1830844
function isNumber(n) {
  return !isNaN(parseFloat(n)) && isFinite(n);
}

function statBonus(statValue) {
    if(!isNumber(statValue)) {
        return false;
    }
    switch(+statValue) { // cast to number
        case 0:
            return "–";
            break;
        case 1:
            return -5;
            break;
        case 2:
            return -3;
            break;
        case 3:
            return 0;
            break;
        case 4:
            return 1;
            break;
        case 5:
            return 3;
            break;
        case 6:
            return 5;
            break;
        case 7:
            return 9;
            break;
        case 8:
            return 15;
            break;
        case 9:
            return 21;
            break;
        default:
            return false;
    }
}

function AppViewModel() {
    this.statStrength = ko.observable();
    this.statEndurance = ko.observable();
    this.statAgility = ko.observable();
    this.statSpeed = ko.observable();

    this.statWillpower = ko.observable();
    this.statInsight = ko.observable();
    this.statReasoning = ko.observable();
    this.statPerception = ko.observable();

    this.statPresence = ko.observable();
    this.statComposure = ko.observable();
    this.statManipulation = ko.observable();
    this.statBeauty = ko.observable();

    this.statBonusStrength = ko.computed(function() {
        return statBonus(this.statStrength());
    }, this);

    this.characterAttributes = [
        {
            name: "Physical",
            attributes: [
                {
                    name: "Strength",
                    score: 0
                },
                {
                    name: "Endurance",
                    score: 0
                },
                {
                    name: "Agility",
                    score: 0
                },
                {
                    name: "Speed",
                    score: 0
                }
            ]
        },
        {
            name: "Mental",
            attributes: [
                {
                    name: "Willpower",
                    score: 0
                },
                {
                    name: "Insight",
                    score: 0
                },
                {
                    name: "Reasoning",
                    score: 0
                },
                {
                    name: "Perception",
                    score: 0
                }
            ]
        },
        {
            name: "Social",
            attributes: [
                {
                    name: "Presence",
                    score: 0
                },
                {
                    name: "Composure",
                    score: 0
                },
                {
                    name: "Manipulation",
                    score: 0
                },
                {
                    name: "Beauty",
                    score: 0
                }
            ]
        }
    ];
}

// Activate knockout.js
ko.applyBindings(new AppViewModel());
<|endoftext|>


<commit_before>/*************************************************
 * Copyright (c) 2017  Ansible, Inc.
 *
 * All Rights Reserved
 *************************************************/

 export default ['i18n', function(i18n) {
     return {
        name: 'nested_groups',
        iterator: 'nested_group',
        editTitle: '{{ inventory.name }}',
        well: true,
        wellOverride: true,
        index: false,
        hover: true,
        multiSelect: true,
        trackBy: 'nested_group.id',
        basePath:  '/api/v2/groups/{{$stateParams.group_id}}/children/',

        fields: {
            failed_hosts: {
                label: '',
                nosort: true,
                mode: 'all',
                iconOnly: true,
                awToolTip: "{{ nested_group.hosts_status_tip }}",
                dataPlacement: "top",
                icon: "{{ 'fa icon-job-' + nested_group.hosts_status_class }}",
                columnClass: 'status-column List-staticColumn--smallStatus'
            },
            name: {
                label: i18n._('Groups'),
                key: true,
                ngClick: "goToGroupGroups(nested_group.id)",
                columnClass: 'col-lg-6 col-md-6 col-sm-6 col-xs-6',
                class: 'InventoryManage-breakWord',
            }
        },

        actions: {
            refresh: {
                mode: 'all',
                awToolTip: i18n._("Refresh the page"),
                ngClick: "refreshGroups()",
                ngShow: "socketStatus == 'error'",
                actionClass: 'btn List-buttonDefault',
                buttonContent: i18n._('REFRESH')
            },
            launch: {
                mode: 'all',
                ngDisabled: '!groupsSelected',
                ngClick: 'setAdhocPattern()',
                awToolTip: i18n._("Select an inventory source by clicking the check box beside it. The inventory source can be a single group or host, a selection of multiple hosts, or a selection of multiple groups."),
                dataPlacement: 'top',
                actionClass: 'btn List-buttonDefault',
                buttonContent: i18n._('RUN COMMANDS'),
                showTipWhenDisabled: true,
                tooltipInnerClass: "Tooltip-wide",
                ngShow: 'canAdhoc'
                // TODO: set up a tip watcher and change text based on when
                // things are selected/not selected.  This is started and
                // commented out in the inventory controller within the watchers.
                // awToolTip: "{{ adhocButtonTipContents }}",
                // dataTipWatch: "adhocButtonTipContents"
            },
            add: {
                mode: 'all',
                type: 'buttonDropdown',
                awToolTip: i18n._("Add a group"),
                actionClass: 'btn List-buttonSubmit',
                buttonContent: '+ ' + i18n._('ADD'),
                ngShow: 'canAdd',
                dataPlacement: "top",
                options: [
                    {
                        optionContent: i18n._('Existing Group'),
                        optionSref: '.associate',
                        ngShow: 'canAdd'
                    },
                    {
                        optionContent: i18n._('New Group'),
                        optionSref: '.add',
                        ngShow: 'canAdd'
                    }
                ],
            }
        },

        fieldActions: {

            columnClass: 'col-lg-6 col-md-6 col-sm-6 col-xs-6 text-right',

            edit: {
                mode: 'all',
                ngClick: "editGroup(nested_group.id)",
                awToolTip: i18n._('Edit group'),
                dataPlacement: "top",
                ngShow: "nested_group.summary_fields.user_capabilities.edit"
            },
            view: {
                mode: 'all',
                ngClick: "editGroup(nested_group.id)",
                awToolTip: i18n._('View group'),
                dataPlacement: "top",
                ngShow: "!nested_group.summary_fields.user_capabilities.edit"
            },
            "delete": {
                mode: 'all',
                ngClick: "disassociateGroup(nested_group)",
                awToolTip: i18n._('Disassociate group'),
                iconClass: 'fa fa-times',
                dataPlacement: "top",
                ngShow: "nested_group.summary_fields.user_capabilities.delete"
            }
        }
    };
}];
<commit_msg>Removed leading slash on basePath<commit_after>/*************************************************
 * Copyright (c) 2017  Ansible, Inc.
 *
 * All Rights Reserved
 *************************************************/

 export default ['i18n', function(i18n) {
     return {
        name: 'nested_groups',
        iterator: 'nested_group',
        editTitle: '{{ inventory.name }}',
        well: true,
        wellOverride: true,
        index: false,
        hover: true,
        multiSelect: true,
        trackBy: 'nested_group.id',
        basePath:  'api/v2/groups/{{$stateParams.group_id}}/children/',

        fields: {
            failed_hosts: {
                label: '',
                nosort: true,
                mode: 'all',
                iconOnly: true,
                awToolTip: "{{ nested_group.hosts_status_tip }}",
                dataPlacement: "top",
                icon: "{{ 'fa icon-job-' + nested_group.hosts_status_class }}",
                columnClass: 'status-column List-staticColumn--smallStatus'
            },
            name: {
                label: i18n._('Groups'),
                key: true,
                ngClick: "goToGroupGroups(nested_group.id)",
                columnClass: 'col-lg-6 col-md-6 col-sm-6 col-xs-6',
                class: 'InventoryManage-breakWord',
            }
        },

        actions: {
            refresh: {
                mode: 'all',
                awToolTip: i18n._("Refresh the page"),
                ngClick: "refreshGroups()",
                ngShow: "socketStatus == 'error'",
                actionClass: 'btn List-buttonDefault',
                buttonContent: i18n._('REFRESH')
            },
            launch: {
                mode: 'all',
                ngDisabled: '!groupsSelected',
                ngClick: 'setAdhocPattern()',
                awToolTip: i18n._("Select an inventory source by clicking the check box beside it. The inventory source can be a single group or host, a selection of multiple hosts, or a selection of multiple groups."),
                dataPlacement: 'top',
                actionClass: 'btn List-buttonDefault',
                buttonContent: i18n._('RUN COMMANDS'),
                showTipWhenDisabled: true,
                tooltipInnerClass: "Tooltip-wide",
                ngShow: 'canAdhoc'
                // TODO: set up a tip watcher and change text based on when
                // things are selected/not selected.  This is started and
                // commented out in the inventory controller within the watchers.
                // awToolTip: "{{ adhocButtonTipContents }}",
                // dataTipWatch: "adhocButtonTipContents"
            },
            add: {
                mode: 'all',
                type: 'buttonDropdown',
                awToolTip: i18n._("Add a group"),
                actionClass: 'btn List-buttonSubmit',
                buttonContent: '+ ' + i18n._('ADD'),
                ngShow: 'canAdd',
                dataPlacement: "top",
                options: [
                    {
                        optionContent: i18n._('Existing Group'),
                        optionSref: '.associate',
                        ngShow: 'canAdd'
                    },
                    {
                        optionContent: i18n._('New Group'),
                        optionSref: '.add',
                        ngShow: 'canAdd'
                    }
                ],
            }
        },

        fieldActions: {

            columnClass: 'col-lg-6 col-md-6 col-sm-6 col-xs-6 text-right',

            edit: {
                mode: 'all',
                ngClick: "editGroup(nested_group.id)",
                awToolTip: i18n._('Edit group'),
                dataPlacement: "top",
                ngShow: "nested_group.summary_fields.user_capabilities.edit"
            },
            view: {
                mode: 'all',
                ngClick: "editGroup(nested_group.id)",
                awToolTip: i18n._('View group'),
                dataPlacement: "top",
                ngShow: "!nested_group.summary_fields.user_capabilities.edit"
            },
            "delete": {
                mode: 'all',
                ngClick: "disassociateGroup(nested_group)",
                awToolTip: i18n._('Disassociate group'),
                iconClass: 'fa fa-times',
                dataPlacement: "top",
                ngShow: "nested_group.summary_fields.user_capabilities.delete"
            }
        }
    };
}];
<|endoftext|>