UNPKG

9.46 kBJavaScriptView Raw
1// @flow
2import * as React from 'react'
3import * as valueTypes from './constants/value_types'
4import type { Observation, Preset } from 'mapeo-schema'
5// import type { Properties as CSSProperties } from 'csstype'
6
7import type {
8 // FeatureCollectionTemplate,
9 Bbox,
10 Point2D,
11 Point3D
12} from 'flow-geojson'
13
14/**
15 * Observation Attachment
16 */
17export type Attachment = $ElementType<
18 $NonMaybeType<$ElementType<Observation, 'attachments'>>,
19 number
20>
21
22// export type StyleProp = CSSProperties<string | number>
23
24// Almost JSON value, but we can also have 'undefined' as a value
25export type JSONValue =
26 | void
27 | null
28 | number
29 | string
30 | boolean
31 | JSONObject // eslint-disable-line no-use-before-define
32 | JSONArray // eslint-disable-line no-use-before-define
33export type JSONObject = { [key: string]: JSONValue }
34type JSONArray = Array<JSONValue>
35type Properties = JSONObject | null
36
37type FlattenedProperties = {
38 [key: string]: null | number | string | boolean
39} | null
40// type FlattenedPropertiesArray = {
41// [key: string]: null | number | string | boolean | JSONArray
42// } | null
43
44type FeatureTemplate<G, P> = {
45 id?: string | number,
46 type: 'Feature',
47 bbox?: Bbox,
48 properties: P,
49 geometry: G
50}
51
52type FeatureTemplateWithId<G, Properties> = FeatureTemplate<G, Properties> & {
53 id: string | number
54}
55
56export type PointFeature = FeatureTemplate<Point2D | Point3D | null, Properties>
57
58export type PointFeatureWithId = FeatureTemplateWithId<
59 Point2D | Point3D | null,
60 Properties
61>
62
63export type FlattenedPointFeature = FeatureTemplate<
64 Point2D | Point3D | null,
65 FlattenedProperties
66>
67
68// export type FeatureCollection = FeatureCollectionTemplate<PointFeature>
69
70export type PaperSize = 'a4' | 'letter'
71
72// Used to store state about field visibility in views
73export type FieldState = Array<{|
74 id: string,
75 hidden: boolean,
76 label: React.Node
77|}>
78export type Filter = Array<number | string | boolean | null | Array<Filter>>
79
80export type ValueTypes = { [fieldkey: string]: $Values<typeof valueTypes> }
81
82export type FieldOrder = { [fieldkey: string]: number }
83
84export type Classes<S> = { [className: $Keys<S>]: string }
85
86export type StringStatistic = {|
87 count: number,
88 lengthMin?: number,
89 lengthMax?: number,
90 lengthVariance?: number,
91 lengthMean?: number,
92 wordsMin?: number,
93 wordsMax?: number,
94 wordsVariance?: number,
95 wordsMean?: number,
96 values: Map<string, number>
97|}
98
99export type NumberStatistic = {|
100 count: number,
101 min?: number,
102 max?: number,
103 variance?: number,
104 mean?: number,
105 values: Map<number, number>
106|}
107
108export type DateStatistic = {|
109 count: number,
110 min?: string,
111 max?: string,
112 mean?: string,
113 values: Map<string, number>
114|}
115
116export type NonArrayFieldStatistic = {|
117 string: StringStatistic,
118 boolean: {|
119 count: number,
120 values: Map<boolean, number>
121 |},
122 number: NumberStatistic,
123 date: DateStatistic,
124 datetime: DateStatistic,
125 url: number,
126 image: number,
127 video: number,
128 audio: number,
129 null: number,
130 undefined: number,
131 location: number
132|}
133
134export type FieldStatistic = {|
135 ...$Exact<NonArrayFieldStatistic>,
136 array?: {|
137 count: number,
138 lengthMin: number,
139 lengthMax: number,
140 valueStats: FieldStatistic
141 |}
142|}
143
144export type Statistics = { [fieldname: string]: FieldStatistic }
145
146type MediaType =
147 | typeof valueTypes.IMAGE_URL
148 | typeof valueTypes.AUDIO_URL
149 | typeof valueTypes.VIDEO_URL
150export type MediaArray = Array<{ src: string, type: MediaType }>
151
152export type Coordinates = {
153 altitude?: number,
154 heading?: number,
155 longitude: number,
156 speed?: number,
157 latitude: number,
158 accuracy?: number
159}
160
161export type Key = string | Array<string | number>
162
163type BaseField = {|
164 // A unique id used to reference the field from presets
165 id: string,
166 // They key in a tags object that this field applies to. For nested
167 // properties, key can be an array e.g. for tags = { foo: { bar: 1 } } the key
168 // is ['foo', 'bar']
169 key: Key,
170 label?: string,
171 // Displayed as a placeholder or hint for the field: use for additional
172 // context or example responses for the user
173 placeholder?: string,
174 // If a field definition contains the property "universal": true, this field will appear in the "Add Field" list for all presets
175 universal?: boolean,
176 // Displayed, but cannot be edited
177 readonly?: boolean
178|}
179
180// type FieldType =
181// | 'text'
182// | 'number'
183// | 'select_one'
184// | 'select_multiple'
185// | 'date'
186// | 'datetime'
187
188export type TextField = {
189 ...BaseField,
190 type: 'text' | 'textarea' | 'localized',
191 appearance?: 'singleline' | 'multiline',
192 // Spaces are replaced with underscores
193 snake_case?: boolean
194}
195
196export type LinkField = {
197 ...BaseField,
198 type: 'link'
199}
200
201export type NumberField = {
202 ...BaseField,
203 type: 'number',
204 min_value?: number,
205 max_value?: number
206}
207
208export type SelectableFieldValue = number | string | boolean | null
209
210export type LabeledSelectOption = {|
211 value: SelectableFieldValue,
212 label: string
213|}
214
215export type SelectOptions = Array<SelectableFieldValue | LabeledSelectOption>
216
217export type SelectOneField = {
218 ...BaseField,
219 type: 'select_one',
220 options: SelectOptions,
221 // User can enter their own reponse if not on the list (defaults to true on
222 // desktop, false on mobile)
223 other?: boolean,
224 // Spaces are replaced with underscores
225 snake_case?: boolean
226}
227
228export type SelectMultipleField = {
229 ...$Exact<SelectOneField>,
230 type: 'select_multiple'
231}
232
233export type DateField = {
234 ...BaseField,
235 type: 'date',
236 min_value?: string,
237 max_value?: string
238}
239
240export type DateTimeField = {
241 ...BaseField,
242 type: 'datetime',
243 min_value?: string,
244 max_value?: string
245}
246
247export type Field =
248 | TextField
249 | NumberField
250 | SelectOneField
251 | SelectMultipleField
252 | DateField
253 | DateTimeField
254 | LinkField
255
256export type MessageDescriptor = {
257 id: string,
258 description?: string | {},
259 defaultMessage?: string
260}
261
262type IntlConfig = {|
263 locale?: string,
264 timeZone?: string,
265 textComponent?: any,
266 messages?: { [key: string]: string },
267 defaultLocale: string,
268 onError?: (err: string) => void
269|}
270
271type FormatDateOptions = {|
272 localeMatcher?: 'lookup' | 'best fit',
273 timeZone?: string,
274 hour12?: boolean,
275 hourCycle?: 'h11' | 'h12' | 'h23' | 'h24',
276 formatMatcher?: 'basic' | 'best fit',
277 weekday?: 'long' | 'short' | 'narrow',
278 era?: 'long' | 'short' | 'narrow',
279 year?: 'numeric' | '2-digit',
280 month?: 'numeric' | '2-digit' | 'long' | 'short' | 'narrow',
281 day?: 'numeric' | '2-digit',
282 hour?: 'numeric' | '2-digit',
283 minute?: 'numeric' | '2-digit',
284 second?: 'numeric' | '2-digit',
285 timeZoneName?: 'long' | 'short'
286|}
287
288type oneToTwenty =
289 | 1
290 | 2
291 | 3
292 | 4
293 | 5
294 | 6
295 | 7
296 | 8
297 | 9
298 | 10
299 | 11
300 | 12
301 | 13
302 | 14
303 | 15
304 | 16
305 | 17
306 | 18
307 | 19
308 | 20
309
310type FormatNumberOptions = {|
311 localeMatcher?: 'lookup' | 'best fit',
312 style?: 'decimal' | 'currency' | 'percent',
313 currenty?: string,
314 currencyDisplay?: 'symbol' | 'code' | 'name',
315 useGrouping?: boolean,
316 minimumIntegerDigits?: oneToTwenty | 21,
317 minimumFractionDigits?: 0 | oneToTwenty,
318 maximumFractionDigits?: 0 | oneToTwenty,
319 minimumSignificantDigits?: oneToTwenty | 21,
320 maximumSignificantDigits?: oneToTwenty | 21
321|}
322
323type FormatRelativeOptions = {|
324 localeMatcher?: 'lookup' | 'best fit',
325 numeric?: 'always' | 'auto',
326 type?: 'long' | 'short' | 'narrow'
327|}
328
329type Unit =
330 | 'second'
331 | 'minute'
332 | 'hour'
333 | 'day'
334 | 'week'
335 | 'month'
336 | 'quarter'
337 | 'year'
338
339type FormatPluralOptions = {
340 type?: 'cardinal' | 'ordinal'
341}
342
343export type Primitive = string | boolean | null | void | number
344
345type MessageValues = { [key: string]: Primitive }
346type IntlFormatters = {|
347 formatDate: (value: number | Date, opts?: FormatDateOptions) => string,
348 formatTime: (value: number | Date, opts?: FormatDateOptions) => string,
349 formatRelativeTime: (
350 value: number,
351 unit: Unit,
352 opts?: FormatRelativeOptions
353 ) => string,
354 formatNumber: (value: number, opts?: FormatNumberOptions) => string,
355 formatPlural: (value: number, opts?: FormatPluralOptions) => string,
356 formatMessage: (
357 descriptor: MessageDescriptor,
358 values?: MessageValues
359 ) => string,
360 formatHTMLMessage: (
361 descriptor: MessageDescriptor,
362 values?: MessageValues
363 ) => string
364|}
365
366export type IntlShape = {|
367 ...IntlConfig,
368 ...IntlFormatters
369|}
370
371/** A function that receives an observation attachment and should return a URL
372 * to retrieve the attachment */
373export type GetMedia = (
374 attachment: Attachment,
375 options?: { width: number, height: number }
376) => { src: string, type: 'image' | 'video' | 'audio' } | void
377
378export type GetMediaUrl = (
379 attachmentId: string,
380 size: 'thumbnail' | 'preview' | 'original'
381) => string
382
383export type GetIconUrl = (iconId: string) => string
384
385export type PresetWithFields = {
386 ...$Exact<Preset>,
387 fields: Field[]
388}
389
390export type PresetWithAdditionalFields = {
391 ...$Exact<PresetWithFields>,
392 additionalFields: Field[]
393}
394
395export type CameraOptions = {
396 center: [number, number],
397 zoom: number,
398 bearing: number,
399 pitch: number
400}
401
402export type CommonViewContentProps = {
403 /** Array of observations to render */
404 observations: Array<Observation>,
405 /** Called with id of observation clicked, optionally with image index */
406 onClick: (id: string, imageIndex?: number) => void,
407 getPreset: Observation => PresetWithAdditionalFields,
408 /**
409 * For a given attachment, return `src` and `type`
410 */
411 getMedia: GetMedia
412}