import React from 'react';
import PropTypes from 'prop-types';
import {
Table
} from 'antd';
import OlFeature from 'ol/feature';
import { get } from 'lodash';
import './PropertyGrid.less';
/**
* Class representing a fature grid showing the attribute values of a simple feature.
*
* @class PropertyGrid
* @extends React.Component
*/
class PropertyGrid extends React.Component {
/**
* The CSS-className added to this component.
* @type {String}
* @private
*/
className = 'react-geo-propertygrid'
/**
* The prop types.
* @type {Object}
*/
static propTypes = {
/**
* Optional title of the attribute name column
* @type {String}
*/
attributeNameColumnTitle: PropTypes.string,
/**
* Optional value in percent representing the width of the attribute name column
* The width of attribute value column wil be calculated depending in this
* @type {String}
*/
attributeNameColumnWidthInPercent: PropTypes.number,
/**
* Optional title of the attribute value column
* @type {String}
*/
attributeValueColumnTitle: PropTypes.string,
/**
* Optional array of attribute names to filter
* @type {Array}
*/
attributeFilter: PropTypes.arrayOf(PropTypes.string),
/**
* Optional object containing a mapping of attribute names in OL feature to custom ones
*
* @type {Object}
*/
attributeNames: PropTypes.object,
/**
* Optional CSS class
* @type {String}
*/
className: PropTypes.string,
/**
* Feature for which the properties should be shown
* @type {OlFeature}
*/
feature: PropTypes.instanceOf(OlFeature).isRequired
}
static defaultProps = {
attributeNameColumnTitle: 'Attribute name',
attributeValueColumnTitle: 'Attribute value',
attributeNameColumnWidthInPercent: 50
}
/**
* The constructor.
*
* @param {Object} props The initial props.
*/
constructor(props) {
super(props);
this.state = {
dataSource: null,
columns: []
};
}
/**
* The componentWillMount function
*/
componentWillMount() {
const {
feature,
attributeFilter,
attributeNames,
attributeNameColumnWidthInPercent
} = this.props;
this.generatePropertyGrid(feature, attributeFilter, attributeNames, attributeNameColumnWidthInPercent);
}
/**
* generatePropertyGrid function
* Initialize data store and column definitions of table
*
* @param {OlFeature} feature feature to display
* @param {Array} attributeFilter Array of string values to filter the grid rows
* @param {Object} attributeNames Object containing mapping of attribute names names in feature to custom ones
* @param {Number} attributeNameColumnWidthInPercent Column width (in percent)
*/
generatePropertyGrid(feature, attributeFilter, attributeNames, attributeNameColumnWidthInPercent) {
if (!attributeFilter) {
attributeFilter = feature.getKeys().filter((attrName) => attrName !== 'geometry');
}
const dataSource = attributeFilter.map((attr) => {
const rowObj = {
attributeName: (attributeNames && get(attributeNames, attr)) ? get(attributeNames, attr) : attr,
attributeValue: feature.get(attr),
key: `ATTR_${attr}_fid_${feature.ol_uid}`
};
return rowObj;
});
const columns = [{
title: this.props.attributeNameColumnTitle,
dataIndex: 'attributeName',
key: 'attributeName',
width: `${attributeNameColumnWidthInPercent}%`
}, {
title: this.props.attributeValueColumnTitle,
dataIndex: 'attributeValue',
key: 'attributeValue',
width: `${100 - attributeNameColumnWidthInPercent}%`
}];
this.setState({
dataSource,
columns
});
}
/**
* The render function.
*
* @return {Element} The element.
*/
render() {
const {
className,
feature,
...passThroughProps
} = this.props;
const {
columns,
dataSource
} = this.state;
const finalClassName = className
? `${className} ${this.className}`
: this.className;
return(
<Table
className={finalClassName}
rowKey={record => record.key}
dataSource={dataSource}
columns={columns}
pagination={false}
useFixedHeader
{...passThroughProps}
/>
);
}
}
export default PropertyGrid;