UNPKG

@attivio/suit

Version:

Attivio SUIT, the Search UI Toolkit, is a library for creating search clients for searching the Attivio platform.

352 lines (294 loc) 12.3 kB
'use strict'; exports.__esModule = true; var _class, _temp; // Uncommenting DrawControl import would enable Polygon selection // feature and render it in Chrome but won't render in IE11. // import DrawControl from 'react-mapbox-gl-draw'; require('@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css'); var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _Glyphicon = require('react-bootstrap/lib/Glyphicon'); var _Glyphicon2 = _interopRequireDefault(_Glyphicon); var _propTypes = require('prop-types'); var _propTypes2 = _interopRequireDefault(_propTypes); var _reactSizeme = require('react-sizeme'); var _reactSizeme2 = _interopRequireDefault(_reactSizeme); var _Configurable = require('../components/Configurable'); var _Configurable2 = _interopRequireDefault(_Configurable); var _SearchFacetBucket = require('../api/SearchFacetBucket'); var _SearchFacetBucket2 = _interopRequireDefault(_SearchFacetBucket); var _PositionUtils = require('../util/PositionUtils'); var _PositionUtils2 = _interopRequireDefault(_PositionUtils); var _ObjectUtils = require('../util/ObjectUtils'); var _ObjectUtils2 = _interopRequireDefault(_ObjectUtils); var _StringUtils = require('../util/StringUtils'); var _StringUtils2 = _interopRequireDefault(_StringUtils); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var ReactMapboxGl = require('react-mapbox-gl'); /** * Component to display the buckets of a facet using a MapBox map. */ var MapFacetContents = (_temp = _class = function (_React$Component) { _inherits(MapFacetContents, _React$Component); MapFacetContents.calcState = function calcState(buckets, zoom, geoFilters, updating) { // Calculate the center from all the coordinates in the buckets. // The output from map() is filtered to remove null values as // getCoordinatesFromBucket() can return null. var center = _PositionUtils2.default.calcCenter(buckets.map(function (bucket) { return MapFacetContents.getCoordinatesFromBucket(bucket); }).filter(function (coordinates) { return coordinates !== null; })); return { latitude: center.latitude, longitude: center.longitude, zoom: zoom, geoFilters: geoFilters, updating: updating }; }; /** * Gets the latitude and longitude from the SearchFacetBucket value. * The SearchFacetBucket value returned from backend can have 2 different formats: * 1. Comma separated string. Eg. "22.56,17.53" * 2. Plain JS Object. Eg. { longitude: 22.56, latitude: 17.53 } * This method returns null if bucket.value is different from these above 2 formats. */ MapFacetContents.getCoordinatesFromBucket = function getCoordinatesFromBucket(bucket) { var value = bucket.value; var longitude = NaN; var latitude = NaN; if (typeof value === 'string') { var valueArr = value.split(','); if (valueArr.length === 2) { longitude = Number.parseFloat(valueArr[0]); latitude = Number.parseFloat(valueArr[1]); } } else { longitude = value.longitude; latitude = value.latitude; } if (Number.isNaN(longitude) || Number.isNaN(latitude)) { return null; } return { longitude: longitude, latitude: latitude }; }; MapFacetContents.getFilter = function getFilter(e) { var filter = 'position:POLYGON('; e.features[0].geometry.coordinates[0].forEach(function (point) { filter = filter + '(' + point[0] + ',' + point[1] + '),'; }); filter = filter.substr(0, filter.length - 1).concat(')'); return filter; }; function MapFacetContents(props) { _classCallCheck(this, MapFacetContents); var _this = _possibleConstructorReturn(this, _React$Component.call(this, props)); _this.state = MapFacetContents.calcState(_this.props.buckets, 1, [], ''); _this.viewportChange = _this.viewportChange.bind(_this); _this.create = _this.create.bind(_this); _this.delete = _this.delete.bind(_this); _this.select = _this.select.bind(_this); _this.update = _this.update.bind(_this); _this.apply = _this.apply.bind(_this); return _this; } MapFacetContents.prototype.componentDidMount = function componentDidMount() { this.handleNewData(this.props.buckets); }; MapFacetContents.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { this.handleNewData(nextProps.buckets); }; MapFacetContents.prototype.shouldComponentUpdate = function shouldComponentUpdate(nextProps, nextState) { var stateTemp = Object.assign({}, this.state); stateTemp.geoFilters = []; stateTemp.proximityBoosts = []; stateTemp.updating = ''; var nextStateTemp = Object.assign({}, nextState); nextStateTemp.geoFilters = []; nextStateTemp.proximityBoosts = []; nextStateTemp.updating = ''; return !_ObjectUtils2.default.deepEquals(this.props.buckets, nextProps.buckets) || !_ObjectUtils2.default.deepEquals(nextStateTemp, stateTemp); }; MapFacetContents.prototype.create = function create(e) { var geoFilters = this.state.geoFilters.slice(); var updating = this.state.updating; updating = MapFacetContents.getFilter(e); geoFilters.push(updating); this.setState({ geoFilters: geoFilters, updating: updating }); }; MapFacetContents.prototype.delete = function _delete(e) { var geoFilters = this.state.geoFilters.slice(); var index = geoFilters.indexOf(MapFacetContents.getFilter(e)); if (index !== -1) { geoFilters.splice(index, 1); } this.setState({ geoFilters: geoFilters, updating: '' }); }; MapFacetContents.prototype.select = function select(e) { var updating = ''; if (e.features.length) { updating = MapFacetContents.getFilter(e); } this.setState({ updating: updating }); }; MapFacetContents.prototype.update = function update(e) { var geoFilters = this.state.geoFilters.slice(); var updating = this.state.updating; updating = MapFacetContents.getFilter(e); var index = geoFilters.indexOf(this.state.updating); if (index !== -1) { geoFilters.splice(index, 1, updating); } this.setState({ geoFilters: geoFilters, updating: updating }); }; MapFacetContents.prototype.apply = function apply() { if (this.context.searcher) { if (this.state.geoFilters.length) { var geoFilter = ''; this.state.geoFilters.forEach(function (filter) { geoFilter = geoFilter ? 'OR(' + filter + ', ' + geoFilter + ')' : filter; }); this.context.searcher.addGeoFilter(geoFilter); } } }; MapFacetContents.prototype.handleNewData = function handleNewData(buckets) { this.setState(MapFacetContents.calcState(buckets, this.state.zoom, this.state.geoFilters, this.state.updating)); }; MapFacetContents.prototype.viewportChange = function viewportChange(viewport) { this.setState({ latitude: viewport.latitude, longitude: viewport.longitude, zoom: viewport.zoom }); }; MapFacetContents.prototype.render = function render() { var _this2 = this; var Marker = ReactMapboxGl.Marker; var ZoomControl = ReactMapboxGl.ZoomControl; if (_StringUtils2.default.notEmpty(this.props.mapboxKey)) { var _Map = ReactMapboxGl.Map({ accessToken: this.props.mapboxKey, attributionControl: false }); var points = this.props.buckets.map(function (bucket) { // Return null if getCoordinatesFromBucket() returns null value var coordinates = MapFacetContents.getCoordinatesFromBucket(bucket); if (!coordinates) { return null; } var longitude = coordinates.longitude, latitude = coordinates.latitude; // Keep track of the boundaries of the coordinates return _react2.default.createElement( Marker, { coordinates: [longitude, latitude], onClick: function onClick() { _this2.props.addFacetFilter(bucket); }, key: longitude + ',' + latitude, style: { cursor: 'pointer' } }, _react2.default.createElement(_Glyphicon2.default, { glyph: 'map-marker', style: { fontSize: '18px', color: '#2a689c' } }) ); }); var height = this.props.size && this.props.size.height ? this.props.size.height : 400; var width = this.props.size && this.props.size.width ? this.props.size.width : 400; // style filters // const selected = ['==', 'active', 'true']; // const deselected = ['==', 'active', 'false']; // const polygon = ['==', '$type', 'Polygon']; // const line = ['==', '$type', 'LineString']; // styles // const selectedColor = '#f9c448'; // const deselectedColor = '#3276b1'; // const lineLayout = { // 'line-cap': 'round', // 'line-join': 'round', // }; // const selectedLinePaint = { // 'line-color': selectedColor, // 'line-dasharray': [0.2, 2], // 'line-width': 2, // }; return _react2.default.createElement( 'div', null, _react2.default.createElement( 'a', { className: 'btn btn-primary btn-xs', style: { position: 'relative', display: 'inline', zIndex: 1, top: '30px', left: '35px' }, role: 'button', tabIndex: 0, onClick: this.apply }, 'Update Results' ), _react2.default.createElement( _Map, { style: 'mapbox://styles/mapbox/light-v9' // eslint-disable-line react/style-prop-object , containerStyle: { height: height, width: width }, center: [this.state.longitude || 0, this.state.latitude || 0], zoom: [this.state.zoom || 1], onStyleLoad: function onStyleLoad(map) { // add a filter query to the state on draw.create map.on('draw.create', _this2.create); // find and remove the appropriate filter query from the state on draw.delete map.on('draw.delete', _this2.delete); // keep track of the selected polygon whenever the selection changes map.on('draw.selectionchange', _this2.select); // find and remove the selected filter from the state then add the updated filter back to it on draw.update map.on('draw.update', _this2.update); } }, _react2.default.createElement(ZoomControl, { position: 'bottom-right' }), points ) ); } return _react2.default.createElement( 'div', { className: 'none' }, 'You must configure a Mapbox key to display map facets.' ); }; return MapFacetContents; }(_react2.default.Component), _class.defaultProps = { size: null, mapboxKey: '' }, _class.contextTypes = { searcher: _propTypes2.default.any }, _class.displayName = 'MapFacetContents', _temp); var hoc = (0, _reactSizeme2.default)({ monitorHeight: true, refreshRate: 10000 }); exports.default = hoc((0, _Configurable2.default)(MapFacetContents)); module.exports = exports['default'];