Last active
September 28, 2016 21:02
-
-
Save zeroasterisk/3c41ace5eff4dde2208d034d5fe4d4eb to your computer and use it in GitHub Desktop.
React Uniforms Field for a map configuration
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import _ from 'lodash'; | |
import { Meteor } from 'meteor/meteor'; | |
import { Session } from 'meteor/session'; | |
import { Bert } from 'meteor/themeteorchef:bert'; | |
import React from 'react'; | |
import { BaseField } from 'uniforms'; | |
import UIMapPoly from 'react-map-polygon-selector'; | |
// ------------------------------------------ | |
// this is the map getMatchData function | |
// must return to the callback the following pattern | |
// callback(null, { matches: 99 }); | |
// @param object mapData { center, bounds, rectangles, polygons, etc. } | |
// @param function callback from UIMapPoly, so it can receive { matches: <val> } | |
// ------------------------------------------ | |
// to ignore matches, replace this with: const getMatchData = _.noop; | |
// ------------------------------------------ | |
const getMatchData = (mapData, callback) => { | |
console.log('getMatchData input', mapData); | |
console.log('getMatchData response handler/Callback', callback); | |
Meteor.call('Buckets.GetMapsMatchData', mapData, (err, res) => { | |
console.log('getMatchData response', err, res); | |
callback(null, res); | |
}); | |
}; | |
// we need to alert if we disallow an overlay | |
const handleOverlayRejected = (reason) => { | |
console.error('Map Overlay Rejected', reason); | |
Bert.error(reason); | |
}; | |
// this is the "base" data for the map, if we don't have a conf.map yet... | |
const getDefaultMap = (bucketId = '') => { | |
const map = { | |
// setting the default bucketId - needed by GetMapsMatchData | |
bucketId, | |
// center: undefined, | |
markers: [], | |
polygons: [], | |
circles: [], | |
rectangles: [], | |
// currentArea: 0, | |
matchData: {}, | |
}; | |
if (!map.center) { | |
// eslint-disable-next-line | |
const defaultCenter = Session.get('defaultMapCenter'); | |
if (defaultCenter) { | |
map.center = defaultCenter; | |
} | |
} | |
return map; | |
}; | |
// sticky map center = faster map loading (less geocoding) | |
const setDefaultCenterFromMapData = mapData => { | |
if (!(mapData && mapData.center)) return; | |
// eslint-disable-next-line | |
Session.set('defaultMapCenter', mapData.center); | |
}; | |
// um... sometimes we are getting some junk in our data from the map | |
// this cleans it for storage into conf.map | |
const cleanMapData = (dataIn) => { | |
const mapData = _.cloneDeep(dataIn); | |
// translate map data into conf | |
Object.keys(mapData).forEach(key => { | |
if (!_.isObject(mapData[key])) return; | |
if (typeof mapData[key].toJSON !== 'function') return; | |
mapData[key] = mapData[key].toJSON(); | |
}); | |
return mapData; | |
}; | |
// Here's the actual Uniforms enabled field | |
// NOTE this is using direct context vs. connectField() | |
// could possibly be refactored... | |
const MapEditField = (props, { uniforms: { model, onChange } }) => { | |
const name = props.name || 'conf.map'; | |
// save data from the map, back into the uniforms model | |
const handleSubmit = (mapData) => { | |
setDefaultCenterFromMapData(mapData); | |
onChange(name, cleanMapData(mapData)); | |
}; | |
let map = _.result(model, name); | |
if (!map) { | |
map = getDefaultMap(); | |
} | |
const bucketId = model._id || 'newBucket'; | |
return ( | |
<UIMapPoly | |
editable={true} | |
getMatchData={(mapData, cb) => { | |
mapData.bucketId = bucketId; | |
getMatchData(mapData, cb); | |
}} | |
handleSubmit={handleSubmit} | |
handleOverlayRejected={handleOverlayRejected} | |
{...map} | |
/> | |
); | |
}; | |
MapEditField.contextTypes = BaseField.contextTypes; | |
MapEditField.propTypes = { | |
name: React.PropTypes.string, | |
}; | |
export default MapEditField; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment