mirror of
https://github.com/EDCD/coriolis.git
synced 2025-12-09 14:45:35 +00:00
134 lines
4.3 KiB
JavaScript
134 lines
4.3 KiB
JavaScript
import React from 'react';
|
|
import TranslatedComponent from './TranslatedComponent';
|
|
import Link from './Link';
|
|
import cn from 'classnames';
|
|
import { outfitURL } from '../utils/UrlGenerators';
|
|
import { SizeMap } from '../shipyard/Constants';
|
|
|
|
|
|
/**
|
|
* Comparison Table
|
|
*/
|
|
export default class ComparisonTable extends TranslatedComponent {
|
|
|
|
static propTypes = {
|
|
facets: React.PropTypes.array.isRequired,
|
|
builds: React.PropTypes.array.isRequired,
|
|
onSort: React.PropTypes.func.isRequired,
|
|
predicate: React.PropTypes.string.isRequired, // Used only to test again prop changes for shouldRender
|
|
desc: React.PropTypes.oneOfType([React.PropTypes.bool.isRequired, React.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 = [
|
|
<th key='ship' rowSpan='2' className='sortable' onClick={onSort.bind(null, 'name')}>{translate('ship')}</th>,
|
|
<th key='build' rowSpan='2' className='sortable' onClick={onSort.bind(null, 'buildName')}>{translate('build')}</th>
|
|
];
|
|
let subHeader = [];
|
|
|
|
for (let f of facets) {
|
|
if (f.active) {
|
|
let p = f.props;
|
|
let pl = p.length;
|
|
header.push(<th key={f.title} rowSpan={pl === 1 ? 2 : 1} colSpan={pl} className={cn({ sortable: pl === 1 })} onClick={pl === 1 ? onSort.bind(null, p[0]) : null }>
|
|
{translate(f.title)}
|
|
</th>);
|
|
|
|
if (pl > 1) {
|
|
for (let i = 0; i < pl; i++) {
|
|
subHeader.push(<th key={p[i]} className={cn('sortable', { lft: i === 0 })} onClick={onSort.bind(null, p[i])} >{translate(f.lbls[i])}</th>);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
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) {
|
|
let url = outfitURL(build.id, build.toString(), build.buildName);
|
|
let cells = [
|
|
<td key='s' className='tl'><Link href={url}>{build.name}</Link></td>,
|
|
<td key='bn' className='tl'><Link href={url}>{build.buildName}</Link></td>
|
|
];
|
|
|
|
for (let f of facets) {
|
|
if (f.active) {
|
|
for (let p of f.props) {
|
|
cells.push(<td key={p}>{formats[f.fmt](build[p])}{f.unit ? units[f.unit] : null}</td>);
|
|
}
|
|
}
|
|
}
|
|
|
|
return <tr key={build.id + build.buildName} className='tr'>{cells}</tr>;
|
|
}
|
|
|
|
/**
|
|
* 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 (
|
|
<div className='scroll-x'>
|
|
<table id='comp-tbl'>
|
|
<thead>
|
|
<tr className='main'>{header}</tr>
|
|
<tr>{subHeader}</tr>
|
|
</thead>
|
|
<tbody>
|
|
{buildsRows}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
);
|
|
}
|
|
}
|