<commit_before>import ChartistGraph from 'react-chartist'
import ChartistLegend from 'chartist-plugin-legend'
import ChartistTooltip from 'chartist-plugin-tooltip'
import React from 'react'
import { injectIntl } from 'react-intl'
import {
  formatSize,
  propTypes
} from 'utils'

// Number of labels on axis X.
const N_LABELS_X = 5

const LABEL_OFFSET_X = 40
const LABEL_OFFSET_Y = 75

const makeOptions = ({ intl, nValues, endTimestamp, interval, valueTransform }) => ({
  showPoint: true,
  lineSmooth: false,
  showArea: true,
  height: 300,
  low: 0,
  axisX: {
    labelInterpolationFnc: makeLabelInterpolationFnc(intl, nValues, endTimestamp, interval),
    offset: LABEL_OFFSET_X
  },
  axisY: {
    labelInterpolationFnc: valueTransform,
    offset: LABEL_OFFSET_Y
  },
  plugins: [
    ChartistLegend(),
    ChartistTooltip({
      valueTransform: value => valueTransform(+value) // '+value' because tooltip gives a string value...
    })
  ]
})

// ===================================================================

const makeLabelInterpolationFnc = (intl, nValues, endTimestamp, interval) => {
  const labelSpace = Math.floor(nValues / N_LABELS_X)
  let format

  if (interval === 3600) {
    format = {
      minute: 'numeric',
      hour: 'numeric',
      weekday: 'short'
    }
  } else if (interval === 86400) {
    format = {
      day: 'numeric',
      month: 'numeric',
      year: 'numeric'
    }
  }

  return (value, index) =>
    index % labelSpace === 0
      ? intl.formatTime((endTimestamp - (nValues - index - 1) * interval) * 1000, format)
      : null
}

const makeObjectSeries = (data, prefix) => {
  const series = []

  for (const io in data) {
    const ioData = data[io]
    for (const letter in ioData) {
      series.push({
        name: `${prefix}${letter} (${io})`,
        data: ioData[letter]
      })
    }
  }

  return series
}

const templateError =

    No stats.

// ===================================================================

export const CpuLineChart = injectIntl(propTypes({
  data: propTypes.object.isRequired,
  options: propTypes.object
})(({ data, options = {}, intl }) => {
  const stats = data.stats.cpus
  const { length } = (stats && stats[0]) || {}

  if (!length) {
    return templateError
  }

  const series = []

  for (const id in stats) {
    series.push({
      name: `Cpu${id}`,
      data: stats[id]
    })
  }

  return (
    <ChartistGraph
      type='Line'
      data={{
        series
      }}
      options={{
        ...makeOptions({
          intl,
          nValues: length,
          endTimestamp: data.endTimestamp,
          interval: data.interval,
          valueTransform: value => `${value}%`
        }),
        high: 100,
        ...options
      }}
    />
  )
}))

export const MemoryLineChart = injectIntl(propTypes({
  data: propTypes.object.isRequired,
  options: propTypes.object
})(({ data, options = {}, intl }) => {
  const {
    memory,
    memoryUsed
  } = data.stats

  if (!memory || !memoryUsed) {
    return templateError
  }

  return (
    <ChartistGraph
      type='Line'
      data={{
        series: [{
          name: 'RAM',
          data: memoryUsed
        }]
      }}
      options={{
        ...makeOptions({
          intl,
          nValues: memoryUsed.length,
          endTimestamp: data.endTimestamp,
          interval: data.interval,
          valueTransform: formatSize
        }),
        high: memory[memory.length - 1],
        ...options
      }}
    />
  )
}))

export const XvdLineChart = injectIntl(propTypes({
  data: propTypes.object.isRequired,
  options: propTypes.object
})(({ data, options = {}, intl }) => {
  const stats = data.stats.xvds
  const { length } = (stats && stats.r.a) || {}

  if (!length) {
    return templateError
  }

  return (
    <ChartistGraph
      type='Line'
      data={{
        series: makeObjectSeries(stats, 'Xvd')
      }}
      options={{
        ...makeOptions({
          intl,
          nValues: length,
          endTimestamp: data.endTimestamp,
          interval: data.interval,
          valueTransform: formatSize
        }),
        ...options
      }}
    />
  )
}))

export const VifLineChart = injectIntl(propTypes({
  data: propTypes.object.isRequired,
  options: propTypes.object
})(({ data, options = {}, intl }) => {
  const stats = data.stats.vifs
  const { length } = (stats && stats.rx[0]) || {}

  if (!length) {
    return templateError
  }

  return (
    <ChartistGraph
      type='Line'
      data={{
        series: makeObjectSeries(stats, 'Vif')
      }}
      options={{
        ...makeOptions({
          intl,
          nValues: length,
          endTimestamp: data.endTimestamp,
          interval: data.interval,
          valueTransform: formatSize
        }),
        ...options
      }}
    />
  )
}))

export const PifLineChart = injectIntl(propTypes({
  data: propTypes.object.isRequired,
  options: propTypes.object
})(({ data, options = {}, intl }) => {
  const stats = data.stats.pifs
  const { length } = (stats && stats.rx[0]) || {}

  if (!length) {
    return templateError
  }

  return (
    <ChartistGraph
      type='Line'
      data={{
        series: makeObjectSeries(stats, 'Pif')
      }}
      options={{
        ...makeOptions({
          intl,
          nValues: length,
          endTimestamp: data.endTimestamp,
          interval: data.interval,
          valueTransform: formatSize
        }),
        ...options
      }}
    />
  )
}))

export const LoadLineChart = injectIntl(propTypes({
  data: propTypes.object.isRequired,
  options: propTypes.object
})(({ data, options = {}, intl }) => {
  const stats = data.stats.load
  const { length } = stats || {}

  if (!length) {
    return templateError
  }

  return (
    <ChartistGraph
      type='Line'
      data={{
        series: [{
          name: 'Load average',
          data: stats
        }]
      }}
      options={{
        ...makeOptions({
          intl,
          nValues: length,
          endTimestamp: data.endTimestamp,
          interval: data.interval,
          valueTransform: value => `${value}`
        }),
        ...options
      }}
    />
  )
}))
<commit_msg>fix(xo-line-chart): set precision on LoadLineChart (#1175)<commit_after>import ChartistGraph from 'react-chartist'
import ChartistLegend from 'chartist-plugin-legend'
import ChartistTooltip from 'chartist-plugin-tooltip'
import React from 'react'
import { injectIntl } from 'react-intl'
import {
  formatSize,
  propTypes
} from 'utils'

// Number of labels on axis X.
const N_LABELS_X = 5

const LABEL_OFFSET_X = 40
const LABEL_OFFSET_Y = 75

const makeOptions = ({ intl, nValues, endTimestamp, interval, valueTransform }) => ({
  showPoint: true,
  lineSmooth: false,
  showArea: true,
  height: 300,
  low: 0,
  axisX: {
    labelInterpolationFnc: makeLabelInterpolationFnc(intl, nValues, endTimestamp, interval),
    offset: LABEL_OFFSET_X
  },
  axisY: {
    labelInterpolationFnc: valueTransform,
    offset: LABEL_OFFSET_Y
  },
  plugins: [
    ChartistLegend(),
    ChartistTooltip({
      valueTransform: value => valueTransform(+value) // '+value' because tooltip gives a string value...
    })
  ]
})

// ===================================================================

const makeLabelInterpolationFnc = (intl, nValues, endTimestamp, interval) => {
  const labelSpace = Math.floor(nValues / N_LABELS_X)
  let format

  if (interval === 3600) {
    format = {
      minute: 'numeric',
      hour: 'numeric',
      weekday: 'short'
    }
  } else if (interval === 86400) {
    format = {
      day: 'numeric',
      month: 'numeric',
      year: 'numeric'
    }
  }

  return (value, index) =>
    index % labelSpace === 0
      ? intl.formatTime((endTimestamp - (nValues - index - 1) * interval) * 1000, format)
      : null
}

const makeObjectSeries = (data, prefix) => {
  const series = []

  for (const io in data) {
    const ioData = data[io]
    for (const letter in ioData) {
      series.push({
        name: `${prefix}${letter} (${io})`,
        data: ioData[letter]
      })
    }
  }

  return series
}

const templateError =

    No stats.

// ===================================================================

export const CpuLineChart = injectIntl(propTypes({
  data: propTypes.object.isRequired,
  options: propTypes.object
})(({ data, options = {}, intl }) => {
  const stats = data.stats.cpus
  const { length } = (stats && stats[0]) || {}

  if (!length) {
    return templateError
  }

  const series = []

  for (const id in stats) {
    series.push({
      name: `Cpu${id}`,
      data: stats[id]
    })
  }

  return (
    <ChartistGraph
      type='Line'
      data={{
        series
      }}
      options={{
        ...makeOptions({
          intl,
          nValues: length,
          endTimestamp: data.endTimestamp,
          interval: data.interval,
          valueTransform: value => `${value}%`
        }),
        high: 100,
        ...options
      }}
    />
  )
}))

export const MemoryLineChart = injectIntl(propTypes({
  data: propTypes.object.isRequired,
  options: propTypes.object
})(({ data, options = {}, intl }) => {
  const {
    memory,
    memoryUsed
  } = data.stats

  if (!memory || !memoryUsed) {
    return templateError
  }

  return (
    <ChartistGraph
      type='Line'
      data={{
        series: [{
          name: 'RAM',
          data: memoryUsed
        }]
      }}
      options={{
        ...makeOptions({
          intl,
          nValues: memoryUsed.length,
          endTimestamp: data.endTimestamp,
          interval: data.interval,
          valueTransform: formatSize
        }),
        high: memory[memory.length - 1],
        ...options
      }}
    />
  )
}))

export const XvdLineChart = injectIntl(propTypes({
  data: propTypes.object.isRequired,
  options: propTypes.object
})(({ data, options = {}, intl }) => {
  const stats = data.stats.xvds
  const { length } = (stats && stats.r.a) || {}

  if (!length) {
    return templateError
  }

  return (
    <ChartistGraph
      type='Line'
      data={{
        series: makeObjectSeries(stats, 'Xvd')
      }}
      options={{
        ...makeOptions({
          intl,
          nValues: length,
          endTimestamp: data.endTimestamp,
          interval: data.interval,
          valueTransform: formatSize
        }),
        ...options
      }}
    />
  )
}))

export const VifLineChart = injectIntl(propTypes({
  data: propTypes.object.isRequired,
  options: propTypes.object
})(({ data, options = {}, intl }) => {
  const stats = data.stats.vifs
  const { length } = (stats && stats.rx[0]) || {}

  if (!length) {
    return templateError
  }

  return (
    <ChartistGraph
      type='Line'
      data={{
        series: makeObjectSeries(stats, 'Vif')
      }}
      options={{
        ...makeOptions({
          intl,
          nValues: length,
          endTimestamp: data.endTimestamp,
          interval: data.interval,
          valueTransform: formatSize
        }),
        ...options
      }}
    />
  )
}))

export const PifLineChart = injectIntl(propTypes({
  data: propTypes.object.isRequired,
  options: propTypes.object
})(({ data, options = {}, intl }) => {
  const stats = data.stats.pifs
  const { length } = (stats && stats.rx[0]) || {}

  if (!length) {
    return templateError
  }

  return (
    <ChartistGraph
      type='Line'
      data={{
        series: makeObjectSeries(stats, 'Pif')
      }}
      options={{
        ...makeOptions({
          intl,
          nValues: length,
          endTimestamp: data.endTimestamp,
          interval: data.interval,
          valueTransform: formatSize
        }),
        ...options
      }}
    />
  )
}))

export const LoadLineChart = injectIntl(propTypes({
  data: propTypes.object.isRequired,
  options: propTypes.object
})(({ data, options = {}, intl }) => {
  const stats = data.stats.load
  const { length } = stats || {}

  if (!length) {
    return templateError
  }

  return (
    <ChartistGraph
      type='Line'
      data={{
        series: [{
          name: 'Load average',
          data: stats
        }]
      }}
      options={{
        ...makeOptions({
          intl,
          nValues: length,
          endTimestamp: data.endTimestamp,
          interval: data.interval,
          valueTransform: value => `${value.toPrecision(3)}`
        }),
        ...options
      }}
    />
  )
}))
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import '../styles/TriedTodos.css';
import TriedTodo from './TriedTodo';
import { connect } from 'react-redux';
import * as actions from '../actions';

class TriedTodos extends Component {
  constructor(props){
    super();
  }

  _getTriedTodos(todos){
    const pastTodos = todos.filter(function(todo){
      if (this._isToday(todo)) {
        return false;
      } else {
        return true;
      }
    }.bind(this));
    return pastTodos.filter(this._isNotCompleted);
  }

  _isNotCompleted(todo){
    return todo.completed === false;
  }

  _isToday(todo){
    const now = new Date();
    const year = now.getFullYear();
    const month = now.getMonth() + 1;
    const day = now.getDate();

    const registeredDate = todo.registeredDate;
    const registeredYear = registeredDate.getFullYear();
    const registeredMonth = registeredDate.getMonth() + 1;
    const registeredDay = registeredDate.getDate();

    return (year === registeredYear) && (month === registeredMonth) && (day === registeredDay);
  }

  render(){
    let triedTodos = this._getTriedTodos(this.props.triedTodos);
    return (

#Tried_Todo

          {triedTodos.map((todo, id) => {
            return <TriedTodo todo={todo} key={id} id={id} updateTriedTodo={this.props.updateTriedTodo}/>
          })}

    );
  }
}

const mapStateToProps = (state) => {
  return {
    triedTodos: state.triedTodos
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    updateTriedTodo: (todo) => { dispatch(actions.toggleTriedTodo(todo)) },
  }
}

export default connect(mapStateToProps,mapDispatchToProps)(TriedTodos);
<commit_msg>[-] TriedTodos 노출 로직 변경<commit_after>import React, { Component } from 'react';
import '../styles/TriedTodos.css';
import TriedTodo from './TriedTodo';
import { connect } from 'react-redux';
import * as actions from '../actions';

class TriedTodos extends Component {
  constructor(props){
    super();
  }

  _isNotCompletedToday(todo){
    const now = new Date();
    const year = now.getFullYear();
    const month = now.getMonth() + 1;
    const day = now.getDate();

    const completedDate = todo.completedDate;
    const completedYear = completedDate.getFullYear();
    const completedMonth = completedDate.getMonth() + 1;
    const completedDay = completedDate.getDate();
    const isNotToday = (year !== completedYear) || (month !== completedMonth) || (day !== completedDay);

    return isNotToday;
  };

  render(){
    return (

#Tried_Todo

          {this.props.triedTodos.map((todo, id) => {
            //오늘 이전에, 이미 완료된 건 렌더 X
            return (todo.completed && this._isNotCompletedToday(todo)) ?
              "" : <TriedTodo todo={todo} key={id} id={id} updateTriedTodo={this.props.updateTriedTodo}/>;
          })}

    );
  }
}

const mapStateToProps = (state) => {
  return {
    triedTodos: state.triedTodos
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    updateTriedTodo: (todo) => { dispatch(actions.toggleTriedTodo(todo)) },
  }
}

export default connect(mapStateToProps,mapDispatchToProps)(TriedTodos);
<|endoftext|>


<commit_before>import React, {Component} from 'react';
import * as FirebaseActions from '../firebaseFunctions';
import cookie from 'react-cookie';
import {Doughnut} from 'react-chartjs-2';

class AuditList extends Component {

	constructor() {
		super();

		// Bind functions that need 'this'
		this.updatePieChart = this.updatePieChart.bind(this);
		this.retrieveUserSpace = this.retrieveUserSpace.bind(this);
		this.renderCourse = this.renderCourse.bind(this);
		this.retrieveCourseHistory = this.retrieveCourseHistory.bind(this);
		this.renderCourseHistory = this.renderCourseHistory.bind(this);
		this.retrieveAuditHistory = this.retrieveAuditHistory.bind(this);
		this.renderAuditHistory = this.renderAuditHistory.bind(this);
		this.renderAudit = this.renderAudit.bind(this);
		this.renderButton = this.renderButton.bind(this);
		this.runAudit = this.runAudit.bind(this);
		this.renderPreview = this.renderPreview.bind(this);

		// Initialize our state
		this.state = {
			courseHistory: [],
			courses: [],
			courseInitialized: true,
			auditHistory: [],
			audits: [],
			auditInitialized: true,
			currentAudit: {},
			chartClass: 'hide',
			chartData:{
				labels:[
					'Completed',
					'Uncompleted'
				],
				datasets:[
					{
						data: [0,0],
						backgroundColor:[
							'#0ef729',
							'#f92020'
						],
						hoverBackgroundColor:[
							'#0ef729',
							'#f92020'
						]
					}
				]
			},
			chartOptions:{
				mantainAspectRatio: false,
				responsive: true
			}
		};
	}

	// On mount of the component, load the audit and check authentication
	componentDidMount(){
		const props = this.props;
		props.checkAuth('AuditList');
		this.retrieveUserSpace();
	}

	/*
	* Return a JSX representation of an audit to be selected in the list
	*/
	renderAudit(audit, selectedAudit) {
		if (selectedAudit == null) {
			selectedAudit = {};
		}
		const auditInfo = (

					<button className="btn btn-flat col s12 m4 l4" onClick={() => {window.location.href = '/audit/' + audit.name;}}>Open Full Audit</button>

 this.renderPreview(audit)} className="clickable col s12 m8 l8"> {audit.name}

		);
		return auditInfo;
	}

	// This function refreshes all state related to the Audit preview
	renderPreview(audit) {
		this.retrieveAuditHistory(audit);
	}

	// This function requests a new audit, if successful routes to the new audit
	runAudit() {
		let auditRequest = new Request('/run/audit', {method: 'POST', credentials: 'same-origin'});
		fetch(auditRequest).then((response) => response.json()).then((response) => {
			if (response.Success) {
				window.location.href = response.auditLink;
			}
		});
	}

	/*
	*	This function will parse, organize, and convert audits
	*		If no parameters are present, parse all audits, add their rendered states to the state
	*		If a single audit is passed in, only re-render that audit, adding new CSS in the process
	*/
	retrieveAuditHistory(selectedAudit){
		if (this.state.auditInitialized) {
			let auditList = [];
			const maxHist = 1000;
			let thisRef = this;

			//take the info off of the top or selected audit
			let top = {};
			if (selectedAudit != null) {
				auditList = this.state.audits;
				top = selectedAudit;
			} else {
				//reverse the order
				auditList = this.state.audits.reverse();
				//remove all but the most recent ones
				if(auditList.length>maxHist){
					auditList.splice(maxHist);
				}
				top = auditList[0];
			}

			//map to their rendered states.
			auditList=auditList.map((audit)=>(thisRef.renderAudit(audit, top)));

			this.setState({
				auditHistory: auditList,
				currentAudit: top,
				courses: top.takenCourses
			});

			this.updatePieChart(top.takenCredits, top.neededCredits);
			this.retrieveCourseHistory(top.takenCourses);
		}
	}

	// Render the list of audits if they exists, otherwise render the option to run one
	renderAuditHistory() {
		if (this.state.auditInitialized) {
			let temp = this.state.auditHistory.slice();
			const exists = (

						{this.state.auditHistory ? temp : '...'}

			);
			return exists;
		} else {
			const notExists = (

You have not run any audits yet!

					<button className="btn" onClick={this.runAudit}>Run Audit</button>

			);
			return notExists;
		}
	}

	/*
	* Retrieve all user information stored on the database for the current user
	* 	This information is then processed and relevant information is applied to state
	*/
	retriveUserSpace() {
		let outerThis = this;
		FirebaseActions.userSpace(cookie.load('TOKEN'), function(response){
			let userSpace = response.userSpace;

			// Retrieve the last audit ran
			if (userSpace.Audits.initialized) {
				let auditsList = [];
				let audits = response.userSpace.Audits;
				for (let audit in audits) {
					if (audits.hasOwnProperty(audit) && audit !== 'initialized') {
						audits[audit].name = audit;
						auditsList.push(audits[audit]);
					}
				}
				outerThis.setState({
					audits: auditsList,
				});
				outerThis.retrieveAuditHistory();
			} else {
				outerThis.setState({
					auditInitialized: response.userSpace.Audits.initialized,
					courseInitialized: false
				});
			}
		});
	}

	/*
	* Simply return JSX for a run audit button, this is called if audits exist already
	*/
	renderButton() {
		if (this.state.auditHistory.length) {
			return <button className="btn" onClick={this.runAudit} style={{marginTop:'15px'}}>Run Another Audit</button>;
		}
	}

	/*
	*	Simply return JSX for a given course
	*/
	renderCourse(course) {
		const courseInfo = (

{course.name}

		);
		return courseInfo;
	}

	/*
	* Parse a list of courses, convert them to their rendered JSX states, apply them to state
	*/
	retrieveCourseHistory(courses) {
		if (courses.length) {
			let courseList = [];
			let maxHist = 100;
			let hist = 0;
			for (let course in courses) {
				if (courses.hasOwnProperty(course) && hist < maxHist) {
					courseList.push(this.renderCourse(courses[course]));
					hist ++;
				}
			}
			this.setState({
				courseHistory: courseList,
			});
		} else {
			this.setState({
				courseInitialized: false
			});
		}
	}

	// Return JSX for the list of rendered courses, if they exist
	renderCourseHistory() {
		if (this.state.courseInitialized) {
			const exists = (

						{this.state.courseHistory.length ? this.state.courseHistory : '...' }

			);
			return exists;
		} else {
			const notExists = (

You had not taken any courses when this audit was generated!

			);
			return notExists;
		}
	}

	// Update the values of the pie chart
	updatePieChart(takenCred, neededCred){
		let oldChartData = this.state.chartData;
		let outerRef = this;
		let credsRemaining = neededCred - takenCred;
		oldChartData.datasets[0].data[0] = takenCred;
		if(credsRemaining<0){
			oldChartData.datasets[0].data[1] = 0;
		}else{
			oldChartData.datasets[0].data[1] = credsRemaining;
		}
		outerRef.setState({
			chartClass: '',
			chartData: oldChartData
		});
	}

	render() {
		return (

Past Audits

								{this.renderButton()}
								{this.renderAuditHistory()}

Completed Credits

										<Doughnut data={this.state.chartData} options={this.state.chartOptions} redraw/>

Classes Taken

									<p2>{this.renderCourseHistory()}</p2>

		);
	}
}

AuditList.contextTypes = {
	router: React.PropTypes.object
};

AuditList.PropTypes = {
	checkAuth: React.PropTypes.func
};

export default AuditList;
<commit_msg>Fix accidental typo that broke site<commit_after>import React, {Component} from 'react';
import * as FirebaseActions from '../firebaseFunctions';
import cookie from 'react-cookie';
import {Doughnut} from 'react-chartjs-2';

class AuditList extends Component {

	constructor() {
		super();

		// Bind functions that need 'this'
		this.updatePieChart = this.updatePieChart.bind(this);
		this.retrieveUserSpace = this.retrieveUserSpace.bind(this);
		this.renderCourse = this.renderCourse.bind(this);
		this.retrieveCourseHistory = this.retrieveCourseHistory.bind(this);
		this.renderCourseHistory = this.renderCourseHistory.bind(this);
		this.retrieveAuditHistory = this.retrieveAuditHistory.bind(this);
		this.renderAuditHistory = this.renderAuditHistory.bind(this);
		this.renderAudit = this.renderAudit.bind(this);
		this.renderButton = this.renderButton.bind(this);
		this.runAudit = this.runAudit.bind(this);
		this.renderPreview = this.renderPreview.bind(this);

		// Initialize our state
		this.state = {
			courseHistory: [],
			courses: [],
			courseInitialized: true,
			auditHistory: [],
			audits: [],
			auditInitialized: true,
			currentAudit: {},
			chartClass: 'hide',
			chartData:{
				labels:[
					'Completed',
					'Uncompleted'
				],
				datasets:[
					{
						data: [0,0],
						backgroundColor:[
							'#0ef729',
							'#f92020'
						],
						hoverBackgroundColor:[
							'#0ef729',
							'#f92020'
						]
					}
				]
			},
			chartOptions:{
				mantainAspectRatio: false,
				responsive: true
			}
		};
	}

	// On mount of the component, load the audit and check authentication
	componentDidMount(){
		const props = this.props;
		props.checkAuth('AuditList');
		this.retrieveUserSpace();
	}

	/*
	* Return a JSX representation of an audit to be selected in the list
	*/
	renderAudit(audit, selectedAudit) {
		if (selectedAudit == null) {
			selectedAudit = {};
		}
		const auditInfo = (

					<button className="btn btn-flat col s12 m4 l4" onClick={() => {window.location.href = '/audit/' + audit.name;}}>Open Full Audit</button>

 this.renderPreview(audit)} className="clickable col s12 m8 l8"> {audit.name}

		);
		return auditInfo;
	}

	// This function refreshes all state related to the Audit preview
	renderPreview(audit) {
		this.retrieveAuditHistory(audit);
	}

	// This function requests a new audit, if successful routes to the new audit
	runAudit() {
		let auditRequest = new Request('/run/audit', {method: 'POST', credentials: 'same-origin'});
		fetch(auditRequest).then((response) => response.json()).then((response) => {
			if (response.Success) {
				window.location.href = response.auditLink;
			}
		});
	}

	/*
	*	This function will parse, organize, and convert audits
	*		If no parameters are present, parse all audits, add their rendered states to the state
	*		If a single audit is passed in, only re-render that audit, adding new CSS in the process
	*/
	retrieveAuditHistory(selectedAudit){
		if (this.state.auditInitialized) {
			let auditList = [];
			const maxHist = 1000;
			let thisRef = this;

			//take the info off of the top or selected audit
			let top = {};
			if (selectedAudit != null) {
				auditList = this.state.audits;
				top = selectedAudit;
			} else {
				//reverse the order
				auditList = this.state.audits.reverse();
				//remove all but the most recent ones
				if(auditList.length>maxHist){
					auditList.splice(maxHist);
				}
				top = auditList[0];
			}

			//map to their rendered states.
			auditList=auditList.map((audit)=>(thisRef.renderAudit(audit, top)));

			this.setState({
				auditHistory: auditList,
				currentAudit: top,
				courses: top.takenCourses
			});

			this.updatePieChart(top.takenCredits, top.neededCredits);
			this.retrieveCourseHistory(top.takenCourses);
		}
	}

	// Render the list of audits if they exists, otherwise render the option to run one
	renderAuditHistory() {
		if (this.state.auditInitialized) {
			let temp = this.state.auditHistory.slice();
			const exists = (

						{this.state.auditHistory ? temp : '...'}

			);
			return exists;
		} else {
			const notExists = (

You have not run any audits yet!

					<button className="btn" onClick={this.runAudit}>Run Audit</button>

			);
			return notExists;
		}
	}

	/*
	* Retrieve all user information stored on the database for the current user
	* 	This information is then processed and relevant information is applied to state
	*/
	retrieveUserSpace() {
		let outerThis = this;
		FirebaseActions.userSpace(cookie.load('TOKEN'), function(response){
			let userSpace = response.userSpace;

			// Retrieve the last audit ran
			if (userSpace.Audits.initialized) {
				let auditsList = [];
				let audits = response.userSpace.Audits;
				for (let audit in audits) {
					if (audits.hasOwnProperty(audit) && audit !== 'initialized') {
						audits[audit].name = audit;
						auditsList.push(audits[audit]);
					}
				}
				outerThis.setState({
					audits: auditsList,
				});
				outerThis.retrieveAuditHistory();
			} else {
				outerThis.setState({
					auditInitialized: response.userSpace.Audits.initialized,
					courseInitialized: false
				});
			}
		});
	}

	/*
	* Simply return JSX for a run audit button, this is called if audits exist already
	*/
	renderButton() {
		if (this.state.auditHistory.length) {
			return <button className="btn" onClick={this.runAudit} style={{marginTop:'15px'}}>Run Another Audit</button>;
		}
	}

	/*
	*	Simply return JSX for a given course
	*/
	renderCourse(course) {
		const courseInfo = (

{course.name}

		);
		return courseInfo;
	}

	/*
	* Parse a list of courses, convert them to their rendered JSX states, apply them to state
	*/
	retrieveCourseHistory(courses) {
		if (courses.length) {
			let courseList = [];
			let maxHist = 100;
			let hist = 0;
			for (let course in courses) {
				if (courses.hasOwnProperty(course) && hist < maxHist) {
					courseList.push(this.renderCourse(courses[course]));
					hist ++;
				}
			}
			this.setState({
				courseHistory: courseList,
			});
		} else {
			this.setState({
				courseInitialized: false
			});
		}
	}

	// Return JSX for the list of rendered courses, if they exist
	renderCourseHistory() {
		if (this.state.courseInitialized) {
			const exists = (

						{this.state.courseHistory.length ? this.state.courseHistory : '...' }

			);
			return exists;
		} else {
			const notExists = (

You had not taken any courses when this audit was generated!

			);
			return notExists;
		}
	}

	// Update the values of the pie chart
	updatePieChart(takenCred, neededCred){
		let oldChartData = this.state.chartData;
		let outerRef = this;
		let credsRemaining = neededCred - takenCred;
		oldChartData.datasets[0].data[0] = takenCred;
		if(credsRemaining<0){
			oldChartData.datasets[0].data[1] = 0;
		}else{
			oldChartData.datasets[0].data[1] = credsRemaining;
		}
		outerRef.setState({
			chartClass: '',
			chartData: oldChartData
		});
	}

	render() {
		return (

Past Audits

								{this.renderButton()}
								{this.renderAuditHistory()}

Completed Credits

										<Doughnut data={this.state.chartData} options={this.state.chartOptions} redraw/>

Classes Taken

									<p2>{this.renderCourseHistory()}</p2>

		);
	}
}

AuditList.contextTypes = {
	router: React.PropTypes.object
};

AuditList.PropTypes = {
	checkAuth: React.PropTypes.func
};

export default AuditList;
<|endoftext|>


<commit_before>/**
 * Checkout.com Magento 2 Payment module (https://www.checkout.com)
 *
 * Copyright (c) 2017 Checkout.com (https://www.checkout.com)
 * Author: David Fiaty | integration@checkout.com
 *
 * License GNU/GPL V3 https://www.gnu.org/licenses/gpl-3.0.en.html
 */

/*browser:true*/
/*global define*/

define(
    [
        'jquery',
        'CheckoutCom_Magento2/js/view/payment/method-renderer/cc-form',
        'CheckoutCom_Magento2/js/view/payment/adapter',
        'Magento_Checkout/js/model/quote',
        'Magento_Ui/js/model/messageList',
        'mage/url',
        'Magento_Checkout/js/action/set-payment-information',
        'Magento_Checkout/js/model/full-screen-loader',
        'Magento_Checkout/js/model/payment/additional-validators',
        'Magento_Checkout/js/checkout-data',
        'Magento_Checkout/js/model/address-converter',
        'Magento_Checkout/js/action/redirect-on-success',
        'mage/translate',
        'mage/cookies'
    ],
    function($, Component, CheckoutCom, quote, globalMessages, url, setPaymentInformationAction, fullScreenLoader, additionalValidators, checkoutData, addressConverter, redirectOnSuccessAction, t, customer) {
        'use strict';

        window.checkoutConfig.reloadOnBillingAddress = true;

        return Component.extend({
            defaults: {
                active: true,
                template: 'CheckoutCom_Magento2/payment/applepay',
                code: 'checkout_com_applepay',
                card_token_id: null,
                button_target: '#cko-applepay-holder button',
                debug: false
            },

            /**
             * @returns {exports}
             */
            initialize: function(config, messageContainer) {
                this._super();
                this.initObservable();
                this.messageContainer = messageContainer || config.messageContainer || globalMessages;
                this.setEmailAddress();

                return this;
            },

            /**
             * @returns {exports}
             */
            initObservable: function () {
                this._super()
                    .observe('isHidden');

                return this;
            },

            /**
             * @returns {bool}
             */
            isVisible: function () {
                return this.isHidden(this.messageContainer.hasMessages());
            },

            /**
             * @returns {bool}
             */
            removeAll: function () {
                this.messageContainer.clear();
            },

            /**
             * @returns {void}
             */
            onHiddenChange: function (isHidden) {
                var self = this;
                // Hide message block if needed
                if (isHidden) {
                    setTimeout(function () {
                        $(self.selector).hide('blind', {}, 500)
                    }, 10000);
                }
            },

            /**
             * @returns {string}
             */
            getCode: function() {
                return CheckoutCom.getCodeApplePay();
            },

            /**
             * @returns {string}
             */
            getApplePayTitle: function() {
                return CheckoutCom.getPaymentConfigApplePay()['title'];
            },

            /**
             * @returns {bool}
             */
            isActive: function() {
                return CheckoutCom.getPaymentConfigApplePay()['isActive'];
            },

            /**
             * @returns {string}
             */
            getEmailAddress: function() {
                return window.checkoutConfig.customerData.email || quote.guestEmail || checkoutData.getValidatedEmailValue();
            },

            /**
             * @returns {void}
             */
            setEmailAddress: function() {
                var email = this.getEmailAddress();
                $.cookie('ckoEmail', email);
            },

            /**
             * @returns {string}
             */
            getPublicKey: function() {
                return CheckoutCom.getPaymentConfig()['public_key'];
            },

            /**
             * @returns {string}
             */
            getQuoteValue: function() {
                return (quote.getTotals()().grand_total).toFixed(2);
            },

            /**
             * @returns {string}
             */
            getQuoteCurrency: function() {
                return CheckoutCom.getPaymentConfig()['quote_currency'];
            },

            /**
             * @returns {object}
             */
            getBillingAddress: function() {
                return quote.billingAddress();
            },

            /**
             * @returns {array}
             */
            getLineItems: function() {
                return [];
            },

            /**
             * @returns {array}
             */
            getSupportedNetworks: function() {
                return CheckoutCom.getPaymentConfigApplePay()['supportedNetworks'].split(',');
            },

            /**
             * @returns {array}
             */
            getSupportedCountries: function() {
                return CheckoutCom.getPaymentConfigApplePay()['supportedCountries'].split(',');
            },

            /**
             * @returns {array}
             */
            getMerchantCapabilities: function() {
                var output = ['supports3DS'];
                var capabilities = CheckoutCom.getPaymentConfigApplePay()['merchantCapabilities'].split(',');

                return output.concat(capabilities);
            },

            /**
             * @returns {void}
             */
            logEvent: function(data) {
                if (this.debug === true) {
                    console.log(data);
                }
            },

            /**
             * @returns {object}
             */
            performValidation: function(valURL) {
                var controllerUrl = url.build('checkout_com/payment/applepayvalidation');
                var validationUrl = controllerUrl + '?u=' + valURL;

                return new Promise(function(resolve, reject) {
                    var xhr = new XMLHttpRequest();
                    xhr.onload = function() {
                        var data = JSON.parse(this.responseText);
                        resolve(data);
                    };
                    xhr.onerror = reject;
                    xhr.open('GET', validationUrl);
                    xhr.send();
                });
            },

            /**
             * @returns {object}
             */
            sendChargeRequest: function(paymentData) {
                return new Promise(function(resolve, reject) {
                    $.ajax({
                        url: url.build('checkout_com/payment/applepayplaceorder'),
                        type: "POST",
                        data: paymentData,
                        success: function(data, textStatus, xhr) {
                            if (data.status === true) {
                                resolve(data.status);
                            }
                            else {
                                reject;
                            }
                        },
                        error: function(xhr, textStatus, error) {
                            reject;
                        }
                    });
                });
            },

            /**
             * @returns {bool}
             */
            launchApplePay: function() {
                // Prepare the parameters
                var ap = CheckoutCom.getPaymentConfigApplePay();
                var self = this;

                // Set the debug mode
                self.debug = JSON.parse(ap['debugMode']);

                // Apply the button style
                $(self.button_target).addClass('apple-pay-button-' + ap['buttonStyle']);

                // Check if the session is available
                if (window.ApplePaySession) {
                    var merchantIdentifier = ap['merchantId'];
                    var promise = ApplePaySession.canMakePaymentsWithActiveCard(merchantIdentifier);
                    promise.then(function (canMakePayments) {
                        if (canMakePayments) {
                            $(self.button_target).css('display', 'block');
                        } else {
                            $('#got_notactive').css('display', 'block');
                        }
                    });
                } else {
                    $('#notgot').css('display', 'block');
                }

                // Handle the events
                $(self.button_target).click(function(evt) {

                    // Validate T&C submission
                    if (!additionalValidators.validate()) {
                        return;
                    }

                    // Prepare the parameters
                    var runningTotal	     = self.getQuoteValue();
                    var billingAddress       = self.getBillingAddress();

                    // Build the payment request
                    var paymentRequest = {
                        currencyCode: CheckoutCom.getPaymentConfig()['quote_currency'],
                        countryCode: billingAddress.countryId,
                        total: {
                           label: ap['storeName'],
                           amount: runningTotal
                        },
                        supportedNetworks: self.getSupportedNetworks(),
                        merchantCapabilities: self.getMerchantCapabilities(),
                        supportedCountries: self.getSupportedCountries()
                    };

                    // Start the payment session
                    var session = new ApplePaySession(1, paymentRequest);

                    // Merchant Validation
                    session.onvalidatemerchant = function (event) {
                        self.logEvent(event);
                        var promise = self.performValidation(event.validationURL);
                        promise.then(function (merchantSession) {
                            session.completeMerchantValidation(merchantSession);
                        });
                    }

                    // Shipping contact
                    session.onshippingcontactselected = function(event) {
                        self.logEvent(event);
                        var status = ApplePaySession.STATUS_SUCCESS;

                        // Shipping info
                        var shippingOptions = [];

                        var newTotal = {
                            type: 'final',
                            label: ap['storeName'],
                            amount: runningTotal
                        };

                        session.completeShippingContactSelection(status, shippingOptions, newTotal, self.getLineItems());
                    }

                    // Shipping method selection
                    session.onshippingmethodselected = function(event) {
                        self.logEvent(event);
                        var status = ApplePaySession.STATUS_SUCCESS;
                        var newTotal = {
                            type: 'final',
                            label: ap['storeName'],
                            amount: runningTotal
                        };

                        session.completeShippingMethodSelection(status, newTotal, self.getLineItems());
                    }

                    // Payment method selection
                    session.onpaymentmethodselected = function(event) {
                        self.logEvent(event);
                        var newTotal = {
                            type: 'final',
                            label: ap['storeName'],
                            amount: runningTotal
                        };

                        session.completePaymentMethodSelection(newTotal, self.getLineItems());
                    }

                    // Payment method authorization
                    session.onpaymentauthorized = function (event) {
                        self.logEvent(event);
                        var promise = self.sendChargeRequest(event.payment.token);
                        promise.then(function (success) {
                            var status;
                            if (success) {
                                status = ApplePaySession.STATUS_SUCCESS;
                            } else {
                                status = ApplePaySession.STATUS_FAILURE;
                            }

                            session.completePayment(status);

                            if (success) {
                                // redirect to success page
                                fullScreenLoader.startLoader();
                                redirectOnSuccessAction.execute();
                            }
                        });
                    }

                    // Session cancellation
                    session.oncancel = function(event) {
                        self.logEvent(event);
                    }

                    // Begin session
                    session.begin();
                });
            },
        });
    }
);<commit_msg>Removed empty line<commit_after>/**
 * Checkout.com Magento 2 Payment module (https://www.checkout.com)
 *
 * Copyright (c) 2017 Checkout.com (https://www.checkout.com)
 * Author: David Fiaty | integration@checkout.com
 *
 * License GNU/GPL V3 https://www.gnu.org/licenses/gpl-3.0.en.html
 */

/*browser:true*/
/*global define*/

define(
    [
        'jquery',
        'CheckoutCom_Magento2/js/view/payment/method-renderer/cc-form',
        'CheckoutCom_Magento2/js/view/payment/adapter',
        'Magento_Checkout/js/model/quote',
        'Magento_Ui/js/model/messageList',
        'mage/url',
        'Magento_Checkout/js/action/set-payment-information',
        'Magento_Checkout/js/model/full-screen-loader',
        'Magento_Checkout/js/model/payment/additional-validators',
        'Magento_Checkout/js/checkout-data',
        'Magento_Checkout/js/model/address-converter',
        'Magento_Checkout/js/action/redirect-on-success',
        'mage/translate',
        'mage/cookies'
    ],
    function($, Component, CheckoutCom, quote, globalMessages, url, setPaymentInformationAction, fullScreenLoader, additionalValidators, checkoutData, addressConverter, redirectOnSuccessAction, t, customer) {
        'use strict';

        window.checkoutConfig.reloadOnBillingAddress = true;

        return Component.extend({
            defaults: {
                active: true,
                template: 'CheckoutCom_Magento2/payment/applepay',
                code: 'checkout_com_applepay',
                card_token_id: null,
                button_target: '#cko-applepay-holder button',
                debug: false
            },

            /**
             * @returns {exports}
             */
            initialize: function(config, messageContainer) {
                this._super();
                this.initObservable();
                this.messageContainer = messageContainer || config.messageContainer || globalMessages;
                this.setEmailAddress();

                return this;
            },

            /**
             * @returns {exports}
             */
            initObservable: function () {
                this._super()
                    .observe('isHidden');

                return this;
            },

            /**
             * @returns {bool}
             */
            isVisible: function () {
                return this.isHidden(this.messageContainer.hasMessages());
            },

            /**
             * @returns {bool}
             */
            removeAll: function () {
                this.messageContainer.clear();
            },

            /**
             * @returns {void}
             */
            onHiddenChange: function (isHidden) {
                var self = this;
                // Hide message block if needed
                if (isHidden) {
                    setTimeout(function () {
                        $(self.selector).hide('blind', {}, 500)
                    }, 10000);
                }
            },

            /**
             * @returns {string}
             */
            getCode: function() {
                return CheckoutCom.getCodeApplePay();
            },

            /**
             * @returns {string}
             */
            getApplePayTitle: function() {
                return CheckoutCom.getPaymentConfigApplePay()['title'];
            },

            /**
             * @returns {bool}
             */
            isActive: function() {
                return CheckoutCom.getPaymentConfigApplePay()['isActive'];
            },

            /**
             * @returns {string}
             */
            getEmailAddress: function() {
                return window.checkoutConfig.customerData.email || quote.guestEmail || checkoutData.getValidatedEmailValue();
            },

            /**
             * @returns {void}
             */
            setEmailAddress: function() {
                var email = this.getEmailAddress();
                $.cookie('ckoEmail', email);
            },

            /**
             * @returns {string}
             */
            getPublicKey: function() {
                return CheckoutCom.getPaymentConfig()['public_key'];
            },

            /**
             * @returns {string}
             */
            getQuoteValue: function() {
                return (quote.getTotals()().grand_total).toFixed(2);
            },

            /**
             * @returns {string}
             */
            getQuoteCurrency: function() {
                return CheckoutCom.getPaymentConfig()['quote_currency'];
            },

            /**
             * @returns {object}
             */
            getBillingAddress: function() {
                return quote.billingAddress();
            },

            /**
             * @returns {array}
             */
            getLineItems: function() {
                return [];
            },

            /**
             * @returns {array}
             */
            getSupportedNetworks: function() {
                return CheckoutCom.getPaymentConfigApplePay()['supportedNetworks'].split(',');
            },

            /**
             * @returns {array}
             */
            getSupportedCountries: function() {
                return CheckoutCom.getPaymentConfigApplePay()['supportedCountries'].split(',');
            },

            /**
             * @returns {array}
             */
            getMerchantCapabilities: function() {
                var output = ['supports3DS'];
                var capabilities = CheckoutCom.getPaymentConfigApplePay()['merchantCapabilities'].split(',');

                return output.concat(capabilities);
            },

            /**
             * @returns {void}
             */
            logEvent: function(data) {
                if (this.debug === true) {
                    console.log(data);
                }
            },

            /**
             * @returns {object}
             */
            performValidation: function(valURL) {
                var controllerUrl = url.build('checkout_com/payment/applepayvalidation');
                var validationUrl = controllerUrl + '?u=' + valURL;

                return new Promise(function(resolve, reject) {
                    var xhr = new XMLHttpRequest();
                    xhr.onload = function() {
                        var data = JSON.parse(this.responseText);
                        resolve(data);
                    };
                    xhr.onerror = reject;
                    xhr.open('GET', validationUrl);
                    xhr.send();
                });
            },

            /**
             * @returns {object}
             */
            sendChargeRequest: function(paymentData) {
                return new Promise(function(resolve, reject) {
                    $.ajax({
                        url: url.build('checkout_com/payment/applepayplaceorder'),
                        type: "POST",
                        data: paymentData,
                        success: function(data, textStatus, xhr) {
                            if (data.status === true) {
                                resolve(data.status);
                            }
                            else {
                                reject;
                            }
                        },
                        error: function(xhr, textStatus, error) {
                            reject;
                        }
                    });
                });
            },

            /**
             * @returns {bool}
             */
            launchApplePay: function() {
                // Prepare the parameters
                var ap = CheckoutCom.getPaymentConfigApplePay();
                var self = this;

                // Set the debug mode
                self.debug = JSON.parse(ap['debugMode']);

                // Apply the button style
                $(self.button_target).addClass('apple-pay-button-' + ap['buttonStyle']);

                // Check if the session is available
                if (window.ApplePaySession) {
                    var merchantIdentifier = ap['merchantId'];
                    var promise = ApplePaySession.canMakePaymentsWithActiveCard(merchantIdentifier);
                    promise.then(function (canMakePayments) {
                        if (canMakePayments) {
                            $(self.button_target).css('display', 'block');
                        } else {
                            $('#got_notactive').css('display', 'block');
                        }
                    });
                } else {
                    $('#notgot').css('display', 'block');
                }

                // Handle the events
                $(self.button_target).click(function(evt) {
                    // Validate T&C submission
                    if (!additionalValidators.validate()) {
                        return;
                    }

                    // Prepare the parameters
                    var runningTotal	     = self.getQuoteValue();
                    var billingAddress       = self.getBillingAddress();

                    // Build the payment request
                    var paymentRequest = {
                        currencyCode: CheckoutCom.getPaymentConfig()['quote_currency'],
                        countryCode: billingAddress.countryId,
                        total: {
                           label: ap['storeName'],
                           amount: runningTotal
                        },
                        supportedNetworks: self.getSupportedNetworks(),
                        merchantCapabilities: self.getMerchantCapabilities(),
                        supportedCountries: self.getSupportedCountries()
                    };

                    // Start the payment session
                    var session = new ApplePaySession(1, paymentRequest);

                    // Merchant Validation
                    session.onvalidatemerchant = function (event) {
                        self.logEvent(event);
                        var promise = self.performValidation(event.validationURL);
                        promise.then(function (merchantSession) {
                            session.completeMerchantValidation(merchantSession);
                        });
                    }

                    // Shipping contact
                    session.onshippingcontactselected = function(event) {
                        self.logEvent(event);
                        var status = ApplePaySession.STATUS_SUCCESS;

                        // Shipping info
                        var shippingOptions = [];

                        var newTotal = {
                            type: 'final',
                            label: ap['storeName'],
                            amount: runningTotal
                        };

                        session.completeShippingContactSelection(status, shippingOptions, newTotal, self.getLineItems());
                    }

                    // Shipping method selection
                    session.onshippingmethodselected = function(event) {
                        self.logEvent(event);
                        var status = ApplePaySession.STATUS_SUCCESS;
                        var newTotal = {
                            type: 'final',
                            label: ap['storeName'],
                            amount: runningTotal
                        };

                        session.completeShippingMethodSelection(status, newTotal, self.getLineItems());
                    }

                    // Payment method selection
                    session.onpaymentmethodselected = function(event) {
                        self.logEvent(event);
                        var newTotal = {
                            type: 'final',
                            label: ap['storeName'],
                            amount: runningTotal
                        };

                        session.completePaymentMethodSelection(newTotal, self.getLineItems());
                    }

                    // Payment method authorization
                    session.onpaymentauthorized = function (event) {
                        self.logEvent(event);
                        var promise = self.sendChargeRequest(event.payment.token);
                        promise.then(function (success) {
                            var status;
                            if (success) {
                                status = ApplePaySession.STATUS_SUCCESS;
                            } else {
                                status = ApplePaySession.STATUS_FAILURE;
                            }

                            session.completePayment(status);

                            if (success) {
                                // redirect to success page
                                fullScreenLoader.startLoader();
                                redirectOnSuccessAction.execute();
                            }
                        });
                    }

                    // Session cancellation
                    session.oncancel = function(event) {
                        self.logEvent(event);
                    }

                    // Begin session
                    session.begin();
                });
            },
        });
    }
);<|endoftext|>


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

var GridSizes = React.createClass({
  handleClick: function(e){
    var grid = parseInt(e.target.id);
    this.props.onClick(grid);
  },

  render: function(){
    var elements = [];
    for(var i=4; i<9; i++){
      elements.push(
{i+"x"+i}
);
    }

    return (

        {elements}

    );
  }
});

module.exports = GridSizes;
<commit_msg>es5 to es6+ syntax<commit_after>import React from 'react';

export default class GridSizes extends React.Component {
  constructor(props) {
    super(props);
    // Operations usually carried out in componentWillMount go here
    // this.handleClick = this.handleClick.bind(this);
  }

  handleClick = (e) => {
    var grid = parseInt(e.target.id);
    this.props.onClick(grid);
  }

  render() {
    let elements = [];
    for(let i=4; i<9; i++){
      elements.push(
{i+"x"+i}
);
    }

    return (

        {elements}

    );
  }

}
<|endoftext|>


<commit_before>import PropTypes from 'prop-types'
import React from 'react'
import icons from './icons'

const Icon = props => {
  const { size, icon, className, ...restProps } = props

  return (
    <svg
      style={{
        display: 'block',
        margin: 'auto',
      }}
      className={className}
      width={`${size}px`}
      height={`${size}px`}
      viewBox={icons[icon].viewBox}
      {...restProps}
    >
      <path d={icons[icon].d}/>
    </svg>
  )
}

Icon.propTypes = {
  icon: PropTypes.string.isRequired,
  size: PropTypes.number,
  className: PropTypes.string,
}

export default Icon
<commit_msg>Remove inline style from Icon svg<commit_after>import PropTypes from 'prop-types'
import React from 'react'
import icons from './icons'

const Icon = props => {
  const { size, icon, ...restProps } = props

  return (
    <svg
      width={`${size}px`}
      height={`${size}px`}
      viewBox={icons[icon].viewBox}
      {...restProps}
    >
      <path d={icons[icon].d}/>
    </svg>
  )
}

Icon.propTypes = {
  icon: PropTypes.string.isRequired,
  size: PropTypes.number,
  className: PropTypes.string,
}

export default Icon
<|endoftext|>


<commit_before>(function(global, $) {
    'use strict';

    function ConcreteInlineStyleCustomizer($element, options) {
        var my = this;
        options = $.extend({
        }, options);

        my.options = options;
        my.$element = $element;
        my.$toolbar = my.$element.find('>ul');
        my.$toolbar.find('div.dropdown-menu').on('click', function(e) {
            if ($(e.target).is('button')) {
                return true;
            } else {
                e.stopPropagation(); // stop the menu from closing
            }
        });

        my.setupForm();
        my.setupButtons();
        my.setupSliders();
    }

    ConcreteInlineStyleCustomizer.prototype = {

        refreshStyles: function(resp) {
            if (resp.oldIssID) {
                $('head').find('style[data-style-set=' + resp.oldIssID +']').remove();
            }
            if (resp.issID) {
                $('head').append($('<style />', {'data-style-set': resp.issID, 'text': resp.css}));
            }
        },

        setupForm: function() {
            var my = this;
            my.$element.concreteAjaxForm({
                success: function(resp) {
                    my.handleResponse(resp);
                },
                error: function(r) {
                    my.$toolbar.prependTo('#ccm-inline-toolbar-container').show();
                }
            });
        },

        setupButtons: function() {
            var my = this;
            my.$toolbar.on('click.inlineStyleCustomizer', 'button[data-action=cancel-design]', function() {
                my.$element.hide();
                ConcreteEvent.fire('EditModeExitInline');
                return false;
            });

            my.$toolbar.on('click.inlineStyleCustomizer', 'button[data-action=reset-design]', function() {
                $.concreteAjax({
                    url: $(this).attr('data-reset-action'),
                    success: function(resp) {
                        my.handleResponse(resp);
                    }
                });
                return false;
            });

            my.$toolbar.on('click.inlineStyleCustomizer', 'button[data-action=save-design]', function() {
                // move the toolbar back into the form so it submits. so great.
                my.$toolbar.hide().prependTo(my.$element);
                my.$element.submit();
                ConcreteEvent.unsubscribe('EditModeExitInlineComplete');
                return false;
            });
        },

        setupSliders: function(){
            var my = this;
            my.$toolbar.find('.ccm-inline-style-sliders').each(function(){
                var targetInput = $(this).children('.ccm-inline-style-slider-value');
                var min = parseInt($(this).attr('data-style-slider-min'));
                var max = parseInt($(this).attr('data-style-slider-max'));
                var currentValue = parseInt($(this).children('.ccm-inline-style-slider-value').val().replace(/\D/g,''));
                if(isNaN(currentValue)) {
                    currentValue = parseInt($(this).attr('data-style-slider-default-setting'));
                }
                $(this).slider({
                    min: min,
                    max: max,
                    value: currentValue,
                    slide: function( event, ui ) {
                        targetInput.prop('disabled', false);
                        var targetInputFormat = targetInput.attr('data-value-format');
                        targetInput.val( ui.value + targetInputFormat );
                        $(this).next('.ccm-inline-style-slider-display-value').text(ui.value + targetInputFormat);
                    }
                });
            });
        }

    }

    function ConcreteBlockInlineStyleCustomizer($element, options) {
        var my = this;
        ConcreteInlineStyleCustomizer.call(my, $element, options);
    }

    ConcreteBlockInlineStyleCustomizer.prototype = Object.create(ConcreteInlineStyleCustomizer.prototype);

    ConcreteBlockInlineStyleCustomizer.prototype.handleResponse = function(resp) {
        var my = this;
        var editor = new Concrete.getEditMode(),
            area = editor.getAreaByID(resp.aID),
            block = area.getBlockByID(parseInt(resp.originalBlockID)),
            arEnableGridContainer = area.getEnableGridContainer() ? 1 : 0,
            action = CCM_DISPATCHER_FILENAME + '/ccm/system/block/render';

        $.get(action, {
            arHandle: area.getHandle(),
            cID: resp.cID,
            bID: resp.bID,
            arEnableGridContainer: arEnableGridContainer
        }, function (r) {
            ConcreteToolbar.disableDirectExit();
            var newBlock = block.replace(r);
            ConcreteAlert.notify({
                'message': resp.message
            });

            my.refreshStyles(resp);

            ConcreteEvent.fire('EditModeExitInline', {
                block: newBlock
            });
        });
    }

    function ConcreteAreaInlineStyleCustomizer($element, options) {
        var my = this;
        ConcreteInlineStyleCustomizer.call(my, $element, options);
    }

    ConcreteAreaInlineStyleCustomizer.prototype = Object.create(ConcreteInlineStyleCustomizer.prototype);

    ConcreteAreaInlineStyleCustomizer.prototype.handleResponse = function(resp) {
        var my = this,
            editor = new Concrete.getEditMode(),
            area = editor.getAreaByID(resp.aID);
        my.refreshStyles(resp);
        area.getElem().removeClassExcept('ccm-area ccm-global-area');
        if (resp.containerClass) {
            area.getElem().addClass(resp.containerClass);
        }
        editor.destroyInlineEditModeToolbars();
    }

    // jQuery Plugin
    $.fn.concreteBlockInlineStyleCustomizer = function (options) {
        return $.each($(this), function (i, obj) {
            new ConcreteBlockInlineStyleCustomizer($(this), options);
        });
    }

    $.fn.concreteAreaInlineStyleCustomizer = function (options) {
        return $.each($(this), function (i, obj) {
            new ConcreteAreaInlineStyleCustomizer($(this), options);
        });
    }

    $.fn.removeClassExcept = function (val) {
        return this.each(function (index, el) {
            var keep = val.split(" "),  // list we'd like to keep
                reAdd = [],          // ones that should be re-added if found
                $el = $(el);       // element we're working on

            // look for which we re-add (based on them already existing)
            for (var i = 0; i < keep.length; i++){
                if ($el.hasClass(keep[i])) reAdd.push(keep[i]);
            }

            // drop all, and only add those confirmed as existing
            $el
                .removeClass()               // remove existing classes
                .addClass(reAdd.join(' '));  // re-add the confirmed ones
        });
    };

    global.ConcreteBlockInlineStyleCustomizer = ConcreteBlockInlineStyleCustomizer;
    global.ConcreteAreaInlineStyleCustomizer = ConcreteAreaInlineStyleCustomizer;

})(this, $);
<commit_msg>Fix Block custom styles<commit_after>(function(global, $) {
    'use strict';

    function ConcreteInlineStyleCustomizer($element, options) {
        var my = this;
        options = $.extend({
        }, options);

        my.options = options;
        my.$element = $element;
        my.$toolbar = my.$element.find('>ul');
        my.$toolbar.find('div.dropdown-menu').on('click', function(e) {
            if ($(e.target).is('button')) {
                return true;
            } else {
                e.stopPropagation(); // stop the menu from closing
            }
        });

        my.setupForm();
        my.setupButtons();
        my.setupSliders();
    }

    ConcreteInlineStyleCustomizer.prototype = {

        refreshStyles: function(resp) {
            if (resp.oldIssID) {
                $('head').find('style[data-style-set=' + resp.oldIssID +']').remove();
            }
            if (resp.issID) {
                $('head').append($('<style />', {'data-style-set': resp.issID, 'text': resp.css}));
            }
        },

        setupForm: function() {
            var my = this;
            my.$element.concreteAjaxForm({
                success: function(resp) {
                    my.handleResponse(resp);
                },
                error: function(r) {
                    my.$toolbar.prependTo('#ccm-inline-toolbar-container').show();
                }
            });
        },

        setupButtons: function() {
            var my = this;
            my.$toolbar.on('click.inlineStyleCustomizer', 'button[data-action=cancel-design]', function() {
                my.$element.hide();
                ConcreteEvent.fire('EditModeExitInline');
                return false;
            });

            my.$toolbar.on('click.inlineStyleCustomizer', 'button[data-action=reset-design]', function() {
                $.concreteAjax({
                    url: $(this).attr('data-reset-action'),
                    success: function(resp) {
                        my.handleResponse(resp);
                    }
                });
                return false;
            });

            my.$toolbar.on('click.inlineStyleCustomizer', 'button[data-action=save-design]', function() {
                // move the toolbar back into the form so it submits. so great.
                my.$toolbar.hide().prependTo(my.$element);
                my.$element.submit();
                ConcreteEvent.unsubscribe('EditModeExitInlineComplete');
                return false;
            });
        },

        setupSliders: function(){
            var my = this;
            my.$toolbar.find('.ccm-inline-style-sliders').each(function(){
                var targetInput = $(this).children('.ccm-inline-style-slider-value');
                var min = parseInt($(this).attr('data-style-slider-min'));
                var max = parseInt($(this).attr('data-style-slider-max'));
                var currentValue = parseInt($(this).children('.ccm-inline-style-slider-value').val().replace(/\D/g,''));
                if(isNaN(currentValue)) {
                    currentValue = parseInt($(this).attr('data-style-slider-default-setting'));
                }
                $(this).slider({
                    min: min,
                    max: max,
                    value: currentValue,
                    slide: function( event, ui ) {
                        targetInput.prop('disabled', false);
                        var targetInputFormat = targetInput.attr('data-value-format');
                        targetInput.val( ui.value + targetInputFormat );
                        $(this).next('.ccm-inline-style-slider-display-value').text(ui.value + targetInputFormat);
                    }
                });
            });
        }

    }

    function ConcreteBlockInlineStyleCustomizer($element, options) {
        var my = this;
        ConcreteInlineStyleCustomizer.call(my, $element, options);
    }

    ConcreteBlockInlineStyleCustomizer.prototype = Object.create(ConcreteInlineStyleCustomizer.prototype);

    ConcreteBlockInlineStyleCustomizer.prototype.handleResponse = function(resp) {
        var my = this;
        var editor = new Concrete.getEditMode(),
            area = editor.getAreaByID(resp.aID),
            block = area.getBlockByID(parseInt(resp.originalBlockID)),
            arEnableGridContainer = area.getEnableGridContainer() ? 1 : 0,
            action = CCM_DISPATCHER_FILENAME + '/ccm/system/block/render';

        if (block.getId() != parseInt(resp.bID)) {
            block.id = parseInt(resp.bID);
        }
        $.get(action, {
            arHandle: area.getHandle(),
            cID: resp.cID,
            bID: resp.bID,
            arEnableGridContainer: arEnableGridContainer
        }, function (r) {
            ConcreteToolbar.disableDirectExit();
            var newBlock = block.replace(r);
            ConcreteAlert.notify({
                'message': resp.message
            });

            my.refreshStyles(resp);
            ConcreteEvent.fire('EditModeExitInline', {
                action: 'save_inline',
                block: newBlock
            });
            ConcreteEvent.fire('EditModeExitInlineComplete', {
                block: newBlock
            });
            $.fn.dialog.hideLoader();
            editor.destroyInlineEditModeToolbars();
            editor.scanBlocks();

        });
    }

    function ConcreteAreaInlineStyleCustomizer($element, options) {
        var my = this;
        ConcreteInlineStyleCustomizer.call(my, $element, options);
    }

    ConcreteAreaInlineStyleCustomizer.prototype = Object.create(ConcreteInlineStyleCustomizer.prototype);

    ConcreteAreaInlineStyleCustomizer.prototype.handleResponse = function(resp) {
        var my = this,
            editor = new Concrete.getEditMode(),
            area = editor.getAreaByID(resp.aID);
        my.refreshStyles(resp);
        area.getElem().removeClassExcept('ccm-area ccm-global-area');
        if (resp.containerClass) {
            area.getElem().addClass(resp.containerClass);
        }
        editor.destroyInlineEditModeToolbars();
    }

    // jQuery Plugin
    $.fn.concreteBlockInlineStyleCustomizer = function (options) {
        return $.each($(this), function (i, obj) {
            new ConcreteBlockInlineStyleCustomizer($(this), options);
        });
    }

    $.fn.concreteAreaInlineStyleCustomizer = function (options) {
        return $.each($(this), function (i, obj) {
            new ConcreteAreaInlineStyleCustomizer($(this), options);
        });
    }

    $.fn.removeClassExcept = function (val) {
        return this.each(function (index, el) {
            var keep = val.split(" "),  // list we'd like to keep
                reAdd = [],          // ones that should be re-added if found
                $el = $(el);       // element we're working on

            // look for which we re-add (based on them already existing)
            for (var i = 0; i < keep.length; i++){
                if ($el.hasClass(keep[i])) reAdd.push(keep[i]);
            }

            // drop all, and only add those confirmed as existing
            $el
                .removeClass()               // remove existing classes
                .addClass(reAdd.join(' '));  // re-add the confirmed ones
        });
    };

    global.ConcreteBlockInlineStyleCustomizer = ConcreteBlockInlineStyleCustomizer;
    global.ConcreteAreaInlineStyleCustomizer = ConcreteAreaInlineStyleCustomizer;

})(this, $);
<|endoftext|>


<commit_before>import React from 'react'
import camelCase from '../helpers/camelCase'
import parseStyle from '../helpers/parseStyle'
import hasDoctype from '../helpers/hasDoctype'

import ATTRIBUTES from '../constants/attributeNames'
import NODE_TYPES from '../constants/nodeTypes'
import { canHaveChildren, canHaveWhitespace } from '../constants/specialTags'

const parser = new DOMParser()

const warnParseErrors = (doc) => {
  const errors = Array.from(doc.documentElement.childNodes)
  // eslint-disable-next-line no-console
  console.warn(`Unable to parse jsx. Found ${errors.length} error(s):`)

  const warn = (node, indent) => {
    if (node.childNodes.length) {
      Array.from(node.childNodes)
        .forEach(n => warn(n, indent.concat(' ')))
    }

    // eslint-disable-next-line no-console
    console.warn(`${indent}==> ${node.nodeValue}`)
  }

  errors.forEach(e => warn(e, ' '))
}

export default class JsxParser extends React.Component {
  constructor(props) {
    super(props)
    this.parseJSX.bind(this)
    this.parseNode.bind(this)

    this.ParsedChildren = this.parseJSX(props.jsx || '')
  }
  componentWillReceiveProps(props) {
    this.ParsedChildren = this.parseJSX(props.jsx || '')
  }

  parseJSX(rawJSX) {
    if (!rawJSX || typeof rawJSX !== 'string') return []

    const jsx = this.props.blacklistedTags.reduce((raw, tag) =>
      raw.replace(new RegExp(`(</?)${tag}`, 'ig'), '$1REMOVE')
    , rawJSX).trim()

    const wrappedJsx = hasDoctype(jsx) ? jsx : `<!DOCTYPE html>\n<html><body>${jsx}</body></html>`

    const doc = parser.parseFromString(wrappedJsx, 'application/xhtml+xml')

    if (!doc) return []

    Array.from(doc.getElementsByTagName('REMOVE')).forEach(tag =>
      tag.parentNode.removeChild(tag)
    )

    const body = doc.getElementsByTagName('body')[0]
    if (!body || body.nodeName.toLowerCase() === 'parseerror') {
      if (this.props.showWarnings) warnParseErrors(doc)
      return []
    }

    const components = this.props.components.reduce(
      (map, type) => ({
        ...map,
        [type.prototype.constructor.name]: type,
      })
    , {})

    return this.parseNode(body.childNodes || [], components)
  }
  parseNode(node, components = {}, key) {
    if (node instanceof NodeList || Array.isArray(node)) {
      return Array.from(node) // handle nodeList or []
        .map((child, index) => this.parseNode(child, components, index))
        .filter(child => child) // remove falsy nodes
    }

    if (node.nodeType === NODE_TYPES.TEXT) {
      // Text node. Collapse whitespace and return it as a String.
      return ('textContent' in node ? node.textContent : node.nodeValue || '')
        .replace(/[\r\n\t\f\v]/g, '')
        .replace(/\s{2,}/g, ' ')
    } else if (node.nodeType === NODE_TYPES.ELEMENT) {
      // Element node. Parse its Attributes and Children, then call createElement
      let children
      if (canHaveChildren(node.nodeName)) {
        children = this.parseNode(node.childNodes, components)
        if (!canHaveWhitespace(node.nodeName)) {
          children = children.filter(child =>
            typeof child !== 'string' || !child.match(/^\s*$/)
          )
        }
      }

      return React.createElement(
        components[node.nodeName] || node.nodeName,
        {
          ...this.props.bindings || {},
          ...this.parseAttrs(node.attributes, key),
        },
        children,
      )
    }

    if (this.props.showWarnings) {
      // eslint-disable-next-line no-console
      console.warn(`JsxParser encountered a(n) ${NODE_TYPES[node.nodeType]} node, and discarded it.`)
    }
    return null
  }

  parseAttrs(attrs, key) {
    if (!attrs || !attrs.length) return { key }

    const blacklist = this.props.blacklistedAttrs

    return Array.from(attrs)
    .filter(attr =>
      !blacklist.map(mask =>
        // If any mask matches, it will return a non-null value
        attr.name.match(new RegExp(mask, 'gi'))
      ).filter(match => match !== null).length
    )
    .reduce((current, attr) => {
      let { name, value } = attr
      if (value === '') value = true

      if (name.match(/^on/i)) {
        value = new Function(value) // eslint-disable-line no-new-func
      } else if (name === 'style') {
        value = parseStyle(value)
      }

      name = ATTRIBUTES[name.toLowerCase()] || camelCase(name)

      return {
        ...current,
        [name]: value,
      }
    }, { key })
  }

  render() {
    return (

        {this.ParsedChildren}

    )
  }
}

if (process.env.NODE_ENV === 'production') {
  // eslint-disable-next-line global-require,import/no-extraneous-dependencies
  const PropTypes = require('prop-types')
  JsxParser.propTypes = {
    // eslint-disable-next-line react/forbid-prop-types
    bindings:         PropTypes.object.isRequired,
    blacklistedAttrs: PropTypes.arrayOf(PropTypes.string),
    blacklistedTags:  PropTypes.arrayOf(PropTypes.string),
    components:       (props, propName) => {
      if (!Array.isArray(props[propName])) {
        return new Error(`${propName} must be an Array of Components.`)
      }

      let passes = true
      props[propName].forEach((component) => {
        if (!(component.prototype instanceof React.Component ||
              component.prototype instanceof React.PureComponent ||
              typeof component === 'function'
          )) {
          passes = false
        }
      })

      return passes ? null : new Error(
        `${propName} must contain only Subclasses of React.Component or React.PureComponent.`
      )
    },
    jsx: PropTypes.string,

    showWarnings: PropTypes.bool,
  }
}
JsxParser.defaultProps = {
  bindings:         {},
  blacklistedAttrs: ['on[a-z]*'],
  blacklistedTags:  ['script'],
  components:       [],
  jsx:              '',
  showWarnings:     false,
}
<commit_msg>Updating outdated PropType warning<commit_after>import React from 'react'
import camelCase from '../helpers/camelCase'
import parseStyle from '../helpers/parseStyle'
import hasDoctype from '../helpers/hasDoctype'

import ATTRIBUTES from '../constants/attributeNames'
import NODE_TYPES from '../constants/nodeTypes'
import { canHaveChildren, canHaveWhitespace } from '../constants/specialTags'

const parser = new DOMParser()

const warnParseErrors = (doc) => {
  const errors = Array.from(doc.documentElement.childNodes)
  // eslint-disable-next-line no-console
  console.warn(`Unable to parse jsx. Found ${errors.length} error(s):`)

  const warn = (node, indent) => {
    if (node.childNodes.length) {
      Array.from(node.childNodes)
        .forEach(n => warn(n, indent.concat(' ')))
    }

    // eslint-disable-next-line no-console
    console.warn(`${indent}==> ${node.nodeValue}`)
  }

  errors.forEach(e => warn(e, ' '))
}

export default class JsxParser extends React.Component {
  constructor(props) {
    super(props)
    this.parseJSX.bind(this)
    this.parseNode.bind(this)

    this.ParsedChildren = this.parseJSX(props.jsx || '')
  }
  componentWillReceiveProps(props) {
    this.ParsedChildren = this.parseJSX(props.jsx || '')
  }

  parseJSX(rawJSX) {
    if (!rawJSX || typeof rawJSX !== 'string') return []

    const jsx = this.props.blacklistedTags.reduce((raw, tag) =>
      raw.replace(new RegExp(`(</?)${tag}`, 'ig'), '$1REMOVE')
    , rawJSX).trim()

    const wrappedJsx = hasDoctype(jsx) ? jsx : `<!DOCTYPE html>\n<html><body>${jsx}</body></html>`

    const doc = parser.parseFromString(wrappedJsx, 'application/xhtml+xml')

    if (!doc) return []

    Array.from(doc.getElementsByTagName('REMOVE')).forEach(tag =>
      tag.parentNode.removeChild(tag)
    )

    const body = doc.getElementsByTagName('body')[0]
    if (!body || body.nodeName.toLowerCase() === 'parseerror') {
      if (this.props.showWarnings) warnParseErrors(doc)
      return []
    }

    const components = this.props.components.reduce(
      (map, type) => ({
        ...map,
        [type.prototype.constructor.name]: type,
      })
    , {})

    return this.parseNode(body.childNodes || [], components)
  }
  parseNode(node, components = {}, key) {
    if (node instanceof NodeList || Array.isArray(node)) {
      return Array.from(node) // handle nodeList or []
        .map((child, index) => this.parseNode(child, components, index))
        .filter(child => child) // remove falsy nodes
    }

    if (node.nodeType === NODE_TYPES.TEXT) {
      // Text node. Collapse whitespace and return it as a String.
      return ('textContent' in node ? node.textContent : node.nodeValue || '')
        .replace(/[\r\n\t\f\v]/g, '')
        .replace(/\s{2,}/g, ' ')
    } else if (node.nodeType === NODE_TYPES.ELEMENT) {
      // Element node. Parse its Attributes and Children, then call createElement
      let children
      if (canHaveChildren(node.nodeName)) {
        children = this.parseNode(node.childNodes, components)
        if (!canHaveWhitespace(node.nodeName)) {
          children = children.filter(child =>
            typeof child !== 'string' || !child.match(/^\s*$/)
          )
        }
      }

      return React.createElement(
        components[node.nodeName] || node.nodeName,
        {
          ...this.props.bindings || {},
          ...this.parseAttrs(node.attributes, key),
        },
        children,
      )
    }

    if (this.props.showWarnings) {
      // eslint-disable-next-line no-console
      console.warn(`JsxParser encountered a(n) ${NODE_TYPES[node.nodeType]} node, and discarded it.`)
    }
    return null
  }

  parseAttrs(attrs, key) {
    if (!attrs || !attrs.length) return { key }

    const blacklist = this.props.blacklistedAttrs

    return Array.from(attrs)
    .filter(attr =>
      !blacklist.map(mask =>
        // If any mask matches, it will return a non-null value
        attr.name.match(new RegExp(mask, 'gi'))
      ).filter(match => match !== null).length
    )
    .reduce((current, attr) => {
      let { name, value } = attr
      if (value === '') value = true

      if (name.match(/^on/i)) {
        value = new Function(value) // eslint-disable-line no-new-func
      } else if (name === 'style') {
        value = parseStyle(value)
      }

      name = ATTRIBUTES[name.toLowerCase()] || camelCase(name)

      return {
        ...current,
        [name]: value,
      }
    }, { key })
  }

  render() {
    return (

        {this.ParsedChildren}

    )
  }
}

if (process.env.NODE_ENV === 'production') {
  // eslint-disable-next-line global-require,import/no-extraneous-dependencies
  const PropTypes = require('prop-types')
  JsxParser.propTypes = {
    // eslint-disable-next-line react/forbid-prop-types
    bindings:         PropTypes.object.isRequired,
    blacklistedAttrs: PropTypes.arrayOf(PropTypes.string),
    blacklistedTags:  PropTypes.arrayOf(PropTypes.string),
    components:       (props, propName) => {
      if (!Array.isArray(props[propName])) {
        return new Error(`${propName} must be an Array of Components.`)
      }

      let passes = true
      props[propName].forEach((component) => {
        if (!(component.prototype instanceof React.Component ||
              component.prototype instanceof React.PureComponent ||
              typeof component === 'function'
          )) {
          passes = false
        }
      })

      return passes ? null : new Error(
        `${propName} must contain only React.Component|PureComponent or functions.`
      )
    },
    jsx: PropTypes.string,

    showWarnings: PropTypes.bool,
  }
}
JsxParser.defaultProps = {
  bindings:         {},
  blacklistedAttrs: ['on[a-z]*'],
  blacklistedTags:  ['script'],
  components:       [],
  jsx:              '',
  showWarnings:     false,
}
<|endoftext|>


<commit_before>// @flow
import React from 'react';

import ViewLayer from './ViewLayer';

import type {Image} from '../image';

const COMPONENT_USE_PROPS = ['isShow', 'imageData'];

export default function LayerList({
  viewLayerDataList,
}: {
  viewLayerDataList: Image[],
}) {
  return viewLayerDataList.map(data => {
    const {id} = data;
    const props = COMPONENT_USE_PROPS.reduce((acc, prop) => {
      acc[prop] = data[prop];
      return acc;
    }, {});
    return <ViewLayer key={id} {...(props: any)} />;
  });
}
<commit_msg>any にキャストしなくてもFlowでエラーが出ないようにした。<commit_after>// @flow
import React from 'react';

import ViewLayer from './ViewLayer';

import type {Image} from '../image';

const COMPONENT_USE_PROPS = ['isShow', 'imageData'];

export default function LayerList({
  viewLayerDataList,
}: {
  viewLayerDataList: Image[],
}) {
  return viewLayerDataList.map(image => {
    const {id} = image;
    const props = Object.assign({}, image);
    const unusedKey = Object.keys(props).filter(key =>
      COMPONENT_USE_PROPS.every(useProps => key !== useProps)
    );
    unusedKey.forEach(key => {
      delete props[key];
    });
    return <ViewLayer key={id} {...props} />;
  });
}
<|endoftext|>


<commit_before>import menu from './Menu.xml';
import TopComponent from '../TopComponent/TopComponent';
import Button from '../Button/Button';
import UserService from '../../services/UserService/UserService';
import router from '../../modules/Router/Router';

import './Menu.scss';

export default class Menu extends TopComponent {
    constructor(data) {
        super('div', {'class': 'menu'}, data);

        this.getElement().innerHTML = menu();
    }

    render() {
        this.getData().buttons.forEach(el => {
            const button = new Button(el.text, el.url);
            this.append(button.render());
        });
        this._logout();
        return this.getElement();
    }

    _logout() {
        const main = this.getElement();
        const logoutButton = main.querySelector('[data-url="/"]');
        if (logoutButton) {
            logoutButton.addEventListener('click', () => {
                UserService.logout()
                    .then(() => {
                        router.getRoute('').getView().rerender();
                        router.go('/');
                    })
                    .catch(response => {
                        response.json().then(json => {
                            console.log(`${response.status}: ${response.statusText}\n${json.message}`);
                        });
                    });
            });
        }
    }
}
<commit_msg>fix Menu<commit_after>import menu from './Menu.xml';
import TopComponent from '../TopComponent/TopComponent';
import Button from '../Button/Button';
import UserService from '../../services/UserService/UserService';
import router from '../../modules/Router/Router';

import './Menu.scss';

export default class Menu extends TopComponent {
    constructor(data) {
        super('div', {'class': 'menu'}, data);

        this.getElement().innerHTML = menu();
    }

    render() {
        this.getData().buttons.forEach(el => {
            const button = new Button(el.text, el.url);
            this.getElement().querySelector('.menu__buttons').appendChild(button.render());
        });
        this._logout();
        return this.getElement();
    }

    _logout() {
        const main = this.getElement();
        const logoutButton = main.querySelector('[data-url="/"]');
        if (logoutButton) {
            logoutButton.addEventListener('click', () => {
                UserService.logout()
                    .then(() => {
                        router.getRoute('').getView().rerender();
                        router.go('/');
                    })
                    .catch(response => {
                        response.json().then(json => {
                            console.log(`${response.status}: ${response.statusText}\n${json.message}`);
                        });
                    });
            });
        }
    }
}
<|endoftext|>