import React from 'react'; import PropTypes from 'prop-types'; import TranslatedComponent from './TranslatedComponent'; import Link from './Link'; import cn from 'classnames'; import { outfitURL } from '../utils/UrlGenerators'; /** * Comparison Table */ export default class ComparisonTable extends TranslatedComponent { static propTypes = { facets: PropTypes.array.isRequired, builds: PropTypes.array.isRequired, onSort: PropTypes.func.isRequired, predicate: PropTypes.string.isRequired, // Used only to test again prop changes for shouldRender desc: PropTypes.oneOfType([PropTypes.bool.isRequired, PropTypes.number.isRequired]), // Used only to test again prop changes for shouldRender }; /** * Constructor * @param {Object} props React Component properties * @param {Object} context React Component context */ constructor(props, context) { super(props, context); this._buildHeaders = this._buildHeaders.bind(this); this.state = this._buildHeaders(props.facets, props.onSort, context.language.translate); } /** * Build table headers * @param {Array} facets Facets list * @param {Function} onSort Sort callback * @param {Function} translate Translate function * @return {Object} Header Components */ _buildHeaders(facets, onSort, translate) { let header = [ {translate('ship')}, {translate('build')} ]; let subHeader = []; for (let f of facets) { if (f.active) { let p = f.props; let pl = p.length; header.push( {translate(f.title)} ); if (pl > 1) { for (let i = 0; i < pl; i++) { subHeader.push({translate(f.lbls[i])}); } } } } return { header, subHeader }; } /** * Generate a table row for the build * @param {Object} build Ship build * @param {Array} facets Facets list * @param {Object} formats Localized formats map * @param {Object} units Localized untis map * @return {React.Component} Table row */ _buildRow(build, facets, formats, units) { if (build && build.id && build.buildName) { let url = outfitURL(build.id, build.toString(), build.buildName); let cells = [ {build.name}, {build.buildName} ]; for (let f of facets) { if (f.active) { for (let p of f.props) { cells.push({formats[f.fmt](build[p])}{f.unit ? units[f.unit] : null}); } } } return {cells}; } } /** * Update state based on property and context changes * @param {Object} nextProps Incoming/Next properties * @param {Object} nextContext Incoming/Next conext */ componentWillReceiveProps(nextProps, nextContext) { // If facets or language has changed re-render header if (nextProps.facets != this.props.facets || nextContext.language != this.context.language) { this.setState(this._buildHeaders(nextProps.facets, nextProps.onSort, nextContext.language.translate)); } } /** * Render the table * @return {React.Component} Comparison table */ render() { let { builds, facets } = this.props; let { header, subHeader } = this.state; let { formats, units } = this.context.language; let buildsRows = new Array(builds.length); for (let i = 0, l = buildsRows.length; i < l; i++) { buildsRows[i] = this._buildRow(builds[i], facets, formats, units); } return (
{header}{subHeader} {buildsRows}
); } }