UNPKG

react-mapfilter

Version:

These components are designed for viewing data in Mapeo. They share a common interface:

166 lines (149 loc) 6.37 kB
import "core-js/modules/es.array.iterator"; import "core-js/modules/web.dom-collections.iterator"; import _findInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/find"; import _filterInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/filter"; import _Object$assign from "@babel/runtime-corejs3/core-js-stable/object/assign"; import _objectWithoutPropertiesLoose from "@babel/runtime-corejs3/helpers/objectWithoutPropertiesLoose"; import _sliceInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/slice"; import _mapInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/map"; import _Array$isArray from "@babel/runtime-corejs3/core-js-stable/array/is-array"; // @flow import * as React from 'react'; import isEqual from 'lodash/isEqual'; import createFilterOrig from 'mapeo-entity-filter'; import ObservationDialog from './ObservationDialog'; import getStats from './stats'; import { defaultGetPreset } from './utils/helpers'; /*:: import type { Observation } from 'mapeo-schema'*/ /*:: import type { PresetWithFields, PresetWithAdditionalFields, GetMedia, Filter, GetIconUrl, GetMediaUrl } from './types'*/ /*:: export type CommonViewProps = { /** Array of observations to render *-/ observations?: Array<Observation>, /** Called when an observation is editing/updated *-/ onUpdateObservation: (observation: Observation) => void, onDeleteObservation: (id: string) => void, /** A function called with an observation that should return a matching preset * with field definitions *-/ presets?: PresetWithFields[], getMediaUrl: GetMediaUrl, getIconUrl?: GetIconUrl, /** Filter to apply to observations *-/ filter?: Filter }*/ /*:: type Props = { ...$Exact<CommonViewProps>, children: ({ filteredObservations: Array<Observation>, onClickObservation: (observationId: string, imageIndex?: number) => void, getPreset: Observation => PresetWithAdditionalFields, getMedia: GetMedia }) => React.Node }*/ const noop = () => {}; // This is a temporary wrapper to compile a filter that defines $preset into a // filter that will work with our dataset, which currently uses categoryId to // define which preset applies. We will need to improve how this works in the // future once we start matching presets like we do with iD const createFilter = (filter /*: Filter | void*/ ) => { if (!_Array$isArray(filter) || filter[0] !== 'all' || filter.length < 2) { return () => true; } const presetFilter = _mapInstanceProperty(filter).call(filter, subFilter => { if (!_Array$isArray(subFilter) || subFilter[1] !== '$preset' && !isEqual(subFilter[1], ['$preset'])) { return subFilter; } return [subFilter[0], 'categoryId', ..._sliceInstanceProperty(subFilter).call(subFilter, 2)]; }); return createFilterOrig(presetFilter); }; const WrappedMapView = (_ref) => { let { observations = [], onUpdateObservation = noop, onDeleteObservation = noop, presets = [], getMediaUrl, filter, children } /*: Props*/ = _ref, otherProps = _objectWithoutPropertiesLoose(_ref, ["observations", "onUpdateObservation", "onDeleteObservation", "presets", "getMediaUrl", "filter", "children"]); const stats = React.useMemo(() => getStats(observations), [observations]); const [editingObservation, setEditingObservation] = React.useState(null); const [editingInitialImageIndex, setEditingInitialImageIndex] = React.useState(); const getPresetWithFallback = React.useCallback((observation /*: Observation*/ ) => /*: PresetWithAdditionalFields*/ { var _context; const preset = getPreset(observation, presets); const defaultPreset = defaultGetPreset(observation, stats); if (!preset) return defaultPreset; return _Object$assign({}, preset, { additionalFields: _filterInstanceProperty(_context = defaultPreset.additionalFields).call(_context, // Any fields that are not defined in the preset we show as 'additionalFields' additionalField => { var _context2; return !_findInstanceProperty(_context2 = preset.fields).call(_context2, field => { const fieldKey = _Array$isArray(field.key) ? field.key : [field.key]; const additionalFieldKey = _Array$isArray(additionalField.key) ? additionalField.key : [additionalField.key]; return isEqual(fieldKey, additionalFieldKey); }); }) }); }, [presets, stats]); const handleObservationClick = React.useCallback((observationId, imageIndex) => { setEditingInitialImageIndex(imageIndex); setEditingObservation(_findInstanceProperty(observations).call(observations, obs => obs.id === observationId)); }, [observations]); const getMedia = React.useCallback((attachment, { width = 800 } = {}) => { const dpr = window.devicePixelRatio; const size = width < 300 * dpr ? 'thumbnail' : width < 1200 * dpr ? 'preview' : 'original'; return { src: getMediaUrl(attachment.id, size), type: 'image' }; }, [getMediaUrl]); const filterFunction = React.useMemo(() => createFilter(filter), [filter]); const filteredObservations = React.useMemo(() => filter ? _filterInstanceProperty(observations).call(observations, filterFunction) : observations, [observations, filterFunction, filter]); return /*#__PURE__*/React.createElement(React.Fragment, null, children({ onClickObservation: handleObservationClick, filteredObservations, getPreset: getPresetWithFallback, getMedia }), /*#__PURE__*/React.createElement(ObservationDialog, { open: !!editingObservation, observation: editingObservation, initialImageIndex: editingInitialImageIndex, getPreset: getPresetWithFallback, getMedia: getMedia, onRequestClose: () => setEditingObservation(false), onSave: onUpdateObservation, onDelete: onDeleteObservation })); }; export default WrappedMapView; // TODO: Update this function to match presets like ID Editor function getPreset(observation /*: Observation*/ , presets /*: PresetWithFields[]*/ ) /*: PresetWithFields | void*/ { const tags = observation.tags; if (!tags || !tags.categoryId) return; const preset = _findInstanceProperty(presets).call(presets, preset => preset.id === tags.categoryId); return preset; } //# sourceMappingURL=ViewWrapper.js.map