Fix more types, migrate two more files

This commit is contained in:
HarelM
2023-12-24 00:42:02 +02:00
parent 08f7a427f6
commit 90f50d98e7
28 changed files with 136 additions and 110 deletions
+10
View File
@@ -75,6 +75,7 @@
"@types/lodash.isequal": "^4.5.8", "@types/lodash.isequal": "^4.5.8",
"@types/lodash.throttle": "^4.1.9", "@types/lodash.throttle": "^4.1.9",
"@types/react": "^16.14.52", "@types/react": "^16.14.52",
"@types/react-aria-menubutton": "^6.2.13",
"@types/react-aria-modal": "^4.0.9", "@types/react-aria-modal": "^4.0.9",
"@types/react-autocomplete": "^1.8.9", "@types/react-autocomplete": "^1.8.9",
"@types/react-collapse": "^5.0.4", "@types/react-collapse": "^5.0.4",
@@ -4889,6 +4890,15 @@
"csstype": "^3.0.2" "csstype": "^3.0.2"
} }
}, },
"node_modules/@types/react-aria-menubutton": {
"version": "6.2.13",
"resolved": "https://registry.npmjs.org/@types/react-aria-menubutton/-/react-aria-menubutton-6.2.13.tgz",
"integrity": "sha512-olSjeIzNzn0KrbShOmBwchHS++khDXBYFTO2U802o8LDHANLms7zUsJhdecfqFpwdFMHxFiMMlCn2nJNCEHWlQ==",
"dev": true,
"dependencies": {
"@types/react": "*"
}
},
"node_modules/@types/react-aria-modal": { "node_modules/@types/react-aria-modal": {
"version": "4.0.9", "version": "4.0.9",
"resolved": "https://registry.npmjs.org/@types/react-aria-modal/-/react-aria-modal-4.0.9.tgz", "resolved": "https://registry.npmjs.org/@types/react-aria-modal/-/react-aria-modal-4.0.9.tgz",
+1
View File
@@ -104,6 +104,7 @@
"@types/lodash.isequal": "^4.5.8", "@types/lodash.isequal": "^4.5.8",
"@types/lodash.throttle": "^4.1.9", "@types/lodash.throttle": "^4.1.9",
"@types/react": "^16.14.52", "@types/react": "^16.14.52",
"@types/react-aria-menubutton": "^6.2.13",
"@types/react-aria-modal": "^4.0.9", "@types/react-aria-modal": "^4.0.9",
"@types/react-autocomplete": "^1.8.9", "@types/react-autocomplete": "^1.8.9",
"@types/react-collapse": "^5.0.4", "@types/react-collapse": "^5.0.4",
+1 -1
View File
@@ -12,7 +12,7 @@ type BlockProps = {
onChange?(...args: unknown[]): unknown onChange?(...args: unknown[]): unknown
fieldSpec?: object fieldSpec?: object
wideMode?: boolean wideMode?: boolean
error?: unknown[] error?: {message: string}
}; };
type BlockState = { type BlockState = {
+3 -1
View File
@@ -5,7 +5,8 @@ import InputString from './InputString'
type FieldCommentProps = { type FieldCommentProps = {
value?: string value?: string
onChange(...args: unknown[]): unknown onChange(value: string | undefined): unknown
error: {message: string}
}; };
export default class FieldComment extends React.Component<FieldCommentProps> { export default class FieldComment extends React.Component<FieldCommentProps> {
@@ -18,6 +19,7 @@ export default class FieldComment extends React.Component<FieldCommentProps> {
label={"Comments"} label={"Comments"}
fieldSpec={fieldSpec} fieldSpec={fieldSpec}
data-wd-key="layer-comment" data-wd-key="layer-comment"
error={this.props.error}
> >
<InputString <InputString
multi={true} multi={true}
+1 -1
View File
@@ -107,7 +107,7 @@ type FieldFunctionProps = {
fieldName: string fieldName: string
fieldType: string fieldType: string
fieldSpec: any fieldSpec: any
errors?: unknown[] errors?: {[key: string]: {message: string}}
value?: any value?: any
}; };
+2 -2
View File
@@ -7,8 +7,8 @@ import InputString from './InputString'
type FieldIdProps = { type FieldIdProps = {
value: string value: string
wdKey: string wdKey: string
onChange(...args: unknown[]): unknown onChange(value: string | undefined): unknown
error?: unknown[] error?: {message: string}
}; };
export default class FieldId extends React.Component<FieldIdProps> { export default class FieldId extends React.Component<FieldIdProps> {
+2 -2
View File
@@ -6,8 +6,8 @@ import InputNumber from './InputNumber'
type FieldMaxZoomProps = { type FieldMaxZoomProps = {
value?: number value?: number
onChange(...args: unknown[]): unknown onChange(value: number | undefined): unknown
error?: unknown[] error?: {message: string}
}; };
export default class FieldMaxZoom extends React.Component<FieldMaxZoomProps> { export default class FieldMaxZoom extends React.Component<FieldMaxZoomProps> {
+1 -1
View File
@@ -7,7 +7,7 @@ import InputNumber from './InputNumber'
type FieldMinZoomProps = { type FieldMinZoomProps = {
value?: number value?: number
onChange(...args: unknown[]): unknown onChange(...args: unknown[]): unknown
error?: unknown[] error?: {message: string}
}; };
export default class FieldMinZoom extends React.Component<FieldMinZoomProps> { export default class FieldMinZoom extends React.Component<FieldMinZoomProps> {
+2 -2
View File
@@ -7,9 +7,9 @@ import InputAutocomplete from './InputAutocomplete'
type FieldSourceProps = { type FieldSourceProps = {
value?: string value?: string
wdKey?: string wdKey?: string
onChange?(...args: unknown[]): unknown onChange?(value: string| undefined): unknown
sourceIds?: unknown[] sourceIds?: unknown[]
error?: unknown[] error?: {message: string}
}; };
export default class FieldSource extends React.Component<FieldSourceProps> { export default class FieldSource extends React.Component<FieldSourceProps> {
+5 -1
View File
@@ -9,6 +9,7 @@ type FieldSourceLayerProps = {
onChange?(...args: unknown[]): unknown onChange?(...args: unknown[]): unknown
sourceLayerIds?: unknown[] sourceLayerIds?: unknown[]
isFixed?: boolean isFixed?: boolean
error?: {message: string}
}; };
export default class FieldSourceLayer extends React.Component<FieldSourceLayerProps> { export default class FieldSourceLayer extends React.Component<FieldSourceLayerProps> {
@@ -19,8 +20,11 @@ export default class FieldSourceLayer extends React.Component<FieldSourceLayerPr
} }
render() { render() {
return <Block label={"Source Layer"} fieldSpec={latest.layer['source-layer']} return <Block
label={"Source Layer"}
fieldSpec={latest.layer['source-layer']}
data-wd-key="layer-source-layer" data-wd-key="layer-source-layer"
error={this.props.error}
> >
<InputAutocomplete <InputAutocomplete
keepMenuWithinWindowBounds={!!this.props.isFixed} keepMenuWithinWindowBounds={!!this.props.isFixed}
+2 -2
View File
@@ -8,8 +8,8 @@ import InputString from './InputString'
type FieldTypeProps = { type FieldTypeProps = {
value: string value: string
wdKey?: string wdKey?: string
onChange(...args: unknown[]): unknown onChange(value: string): unknown
error?: unknown[] | undefined error?: {message: string}
disabled?: boolean disabled?: boolean
}; };
@@ -1,10 +1,9 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types'
import {combiningFilterOps} from '../libs/filterops' import {combiningFilterOps} from '../libs/filterops'
import {mdiTableRowPlusAfter} from '@mdi/js'; import {mdiTableRowPlusAfter} from '@mdi/js';
import {isEqual} from 'lodash'; import {isEqual} from 'lodash';
import {latest, migrate, convertFilter} from '@maplibre/maplibre-gl-style-spec' import {latest, migrate, convertFilter, ExpressionSpecification, LegacyFilterSpecification, StyleSpecification} from '@maplibre/maplibre-gl-style-spec'
import InputSelect from './InputSelect' import InputSelect from './InputSelect'
import Block from './Block' import Block from './Block'
import SingleFilterEditor from './SingleFilterEditor' import SingleFilterEditor from './SingleFilterEditor'
@@ -15,7 +14,7 @@ import ExpressionProperty from './_ExpressionProperty';
import {mdiFunctionVariant} from '@mdi/js'; import {mdiFunctionVariant} from '@mdi/js';
function combiningFilter (props) { function combiningFilter(props: FilterEditorProps): LegacyFilterSpecification | ExpressionSpecification {
let filter = props.filter || ['all']; let filter = props.filter || ['all'];
if (!Array.isArray(filter)) { if (!Array.isArray(filter)) {
@@ -30,14 +29,14 @@ function combiningFilter (props) {
filters = [filter.slice(0)]; filters = [filter.slice(0)];
} }
return [combiningOp, ...filters]; return [combiningOp, ...filters] as LegacyFilterSpecification | ExpressionSpecification;
} }
function migrateFilter (filter) { function migrateFilter(filter: LegacyFilterSpecification | ExpressionSpecification) {
return migrate(createStyleFromFilter(filter)).layers[0].filter; return (migrate(createStyleFromFilter(filter)).layers[0] as any).filter;
} }
function createStyleFromFilter (filter) { function createStyleFromFilter(filter: LegacyFilterSpecification | ExpressionSpecification): StyleSpecification & {id: string} {
return { return {
"id": "tmp", "id": "tmp",
"version": 8, "version": 8,
@@ -69,7 +68,7 @@ const FILTER_OPS = [
]; ];
// If we convert a filter that is an expression to an expression it'll remain the same in value // If we convert a filter that is an expression to an expression it'll remain the same in value
function checkIfSimpleFilter (filter) { function checkIfSimpleFilter (filter: LegacyFilterSpecification | ExpressionSpecification) {
if (filter.length === 1 && FILTER_OPS.includes(filter[0])) { if (filter.length === 1 && FILTER_OPS.includes(filter[0])) {
return true; return true;
} }
@@ -77,33 +76,38 @@ function checkIfSimpleFilter (filter) {
return !isEqual(expression, filter); return !isEqual(expression, filter);
} }
function hasCombiningFilter(filter) { function hasCombiningFilter(filter: LegacyFilterSpecification | ExpressionSpecification) {
return combiningFilterOps.indexOf(filter[0]) >= 0 return combiningFilterOps.indexOf(filter[0]) >= 0
} }
function hasNestedCombiningFilter(filter) { function hasNestedCombiningFilter(filter: LegacyFilterSpecification | ExpressionSpecification) {
if(hasCombiningFilter(filter)) { if(hasCombiningFilter(filter)) {
const combinedFilters = filter.slice(1) return filter.slice(1).map(f => hasCombiningFilter(f as any)).filter(f => f == true).length > 0
return filter.slice(1).map(f => hasCombiningFilter(f)).filter(f => f == true).length > 0
} }
return false return false
} }
export default class FilterEditor extends React.Component { type FilterEditorProps = {
static propTypes = { /** Properties of the vector layer and the available fields */
/** Properties of the vector layer and the available fields */ properties?: {[key:string]: any}
properties: PropTypes.object, filter?: any[]
filter: PropTypes.array, errors?: {[key:string]: any}
errors: PropTypes.object, onChange(value: LegacyFilterSpecification | ExpressionSpecification): unknown
onChange: PropTypes.func.isRequired, };
}
type FilterEditorState = {
showDoc: boolean
displaySimpleFilter: boolean
valueIsSimpleFilter?: boolean
};
export default class FilterEditor extends React.Component<FilterEditorProps, FilterEditorState> {
static defaultProps = { static defaultProps = {
filter: ["all"], filter: ["all"],
} }
constructor (props) { constructor (props: FilterEditorProps) {
super(); super(props);
this.state = { this.state = {
showDoc: false, showDoc: false,
displaySimpleFilter: checkIfSimpleFilter(combiningFilter(props)), displaySimpleFilter: checkIfSimpleFilter(combiningFilter(props)),
@@ -111,25 +115,25 @@ export default class FilterEditor extends React.Component {
} }
// Convert filter to combining filter // Convert filter to combining filter
onFilterPartChanged(filterIdx, newPart) { onFilterPartChanged(filterIdx: number, newPart: any[]) {
const newFilter = combiningFilter(this.props).slice(0) const newFilter = combiningFilter(this.props).slice(0) as LegacyFilterSpecification | ExpressionSpecification
newFilter[filterIdx] = newPart newFilter[filterIdx] = newPart
this.props.onChange(newFilter) this.props.onChange(newFilter)
} }
deleteFilterItem(filterIdx) { deleteFilterItem(filterIdx: number) {
const newFilter = combiningFilter(this.props).slice(0) const newFilter = combiningFilter(this.props).slice(0) as LegacyFilterSpecification | ExpressionSpecification
newFilter.splice(filterIdx + 1, 1) newFilter.splice(filterIdx + 1, 1)
this.props.onChange(newFilter) this.props.onChange(newFilter)
} }
addFilterItem = () => { addFilterItem = () => {
const newFilterItem = combiningFilter(this.props).slice(0) const newFilterItem = combiningFilter(this.props).slice(0) as LegacyFilterSpecification | ExpressionSpecification
newFilterItem.push(['==', 'name', '']) (newFilterItem as any[]).push(['==', 'name', ''])
this.props.onChange(newFilterItem) this.props.onChange(newFilterItem)
} }
onToggleDoc = (val) => { onToggleDoc = (val: boolean) => {
this.setState({ this.setState({
showDoc: val showDoc: val
}); });
@@ -149,8 +153,7 @@ export default class FilterEditor extends React.Component {
}) })
} }
static getDerivedStateFromProps (props, currentState) { static getDerivedStateFromProps(props: FilterEditorProps, currentState: FilterEditorState) {
const {filter} = props;
const displaySimpleFilter = checkIfSimpleFilter(combiningFilter(props)); const displaySimpleFilter = checkIfSimpleFilter(combiningFilter(props));
// Upgrade but never downgrade // Upgrade but never downgrade
@@ -178,7 +181,7 @@ export default class FilterEditor extends React.Component {
const fieldSpec={ const fieldSpec={
doc: latest.layer.filter.doc + " Combine multiple filters together by using a compound filter." doc: latest.layer.filter.doc + " Combine multiple filters together by using a compound filter."
}; };
const defaultFilter = ["all"]; const defaultFilter = ["all"] as LegacyFilterSpecification | ExpressionSpecification;
const isNestedCombiningFilter = displaySimpleFilter && hasNestedCombiningFilter(combiningFilter(this.props)); const isNestedCombiningFilter = displaySimpleFilter && hasNestedCombiningFilter(combiningFilter(this.props));
@@ -201,7 +204,7 @@ export default class FilterEditor extends React.Component {
else if (displaySimpleFilter) { else if (displaySimpleFilter) {
const filter = combiningFilter(this.props); const filter = combiningFilter(this.props);
let combiningOp = filter[0]; let combiningOp = filter[0];
let filters = filter.slice(1) let filters = filter.slice(1) as (LegacyFilterSpecification | ExpressionSpecification)[];
const actions = ( const actions = (
<div> <div>
@@ -218,7 +221,7 @@ export default class FilterEditor extends React.Component {
); );
const editorBlocks = filters.map((f, idx) => { const editorBlocks = filters.map((f, idx) => {
const error = errors[`filter[${idx+1}]`]; const error = errors![`filter[${idx+1}]`];
return ( return (
<div key={`block-${idx}`}> <div key={`block-${idx}`}>
@@ -247,7 +250,7 @@ export default class FilterEditor extends React.Component {
> >
<InputSelect <InputSelect
value={combiningOp} value={combiningOp}
onChange={this.onFilterPartChanged.bind(this, 0)} onChange={(v: [string, any]) => this.onFilterPartChanged(0, v)}
options={[["all", "every filter matches"], ["none", "no filter matches"], ["any", "any filter matches"]]} options={[["all", "every filter matches"], ["none", "no filter matches"], ["any", "any filter matches"]]}
/> />
</Block> </Block>
+1 -1
View File
@@ -8,7 +8,7 @@ const MAX_HEIGHT = 140;
export type InputAutocompleteProps = { export type InputAutocompleteProps = {
value?: string value?: string
options: any[] options: any[]
onChange(...args: unknown[]): unknown onChange(value: string | undefined): unknown
keepMenuWithinWindowBounds?: boolean keepMenuWithinWindowBounds?: boolean
'aria-label'?: string 'aria-label'?: string
}; };
+1 -1
View File
@@ -5,7 +5,7 @@ export type InputSelectProps = {
"data-wd-key"?: string "data-wd-key"?: string
options: [string, any][] | string[] options: [string, any][] | string[]
style?: object style?: object
onChange(value: string): unknown onChange(value: string | [string, any]): unknown
title?: string title?: string
'aria-label'?: string 'aria-label'?: string
}; };
@@ -1,6 +1,8 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { Wrapper, Button, Menu, MenuItem } from 'react-aria-menubutton' import { Wrapper, Button, Menu, MenuItem } from 'react-aria-menubutton'
import {Accordion} from 'react-accessible-accordion';
import {MdMoreVert} from 'react-icons/md'
import FieldJson from './FieldJson' import FieldJson from './FieldJson'
import FilterEditor from './FilterEditor' import FilterEditor from './FilterEditor'
@@ -13,20 +15,18 @@ import FieldMaxZoom from './FieldMaxZoom'
import FieldComment from './FieldComment' import FieldComment from './FieldComment'
import FieldSource from './FieldSource' import FieldSource from './FieldSource'
import FieldSourceLayer from './FieldSourceLayer' import FieldSourceLayer from './FieldSourceLayer'
import {Accordion} from 'react-accessible-accordion';
import {MdMoreVert} from 'react-icons/md'
import { changeType, changeProperty } from '../libs/layer' import { changeType, changeProperty } from '../libs/layer'
import layout from '../config/layout.json' import layout from '../config/layout.json'
import {formatLayerId} from '../util/format'; import {formatLayerId} from '../util/format';
import { SourceSpecification } from '@maplibre/maplibre-gl-style-spec';
import { BackgroundLayerSpecification, LayerSpecification } from 'maplibre-gl';
function getLayoutForType (type) { function getLayoutForType(type: LayerSpecification["type"]) {
return layout[type] ? layout[type] : layout.invalid; return layout[type] ? layout[type] : layout.invalid;
} }
function layoutGroups(layerType) { function layoutGroups(layerType: LayerSpecification["type"]): {title: string, type: string, fields?: string[]}[] {
const layerGroup = { const layerGroup = {
title: 'Layer', title: 'Layer',
type: 'layer' type: 'layer'
@@ -44,25 +44,29 @@ function layoutGroups(layerType) {
.concat([editorGroup]) .concat([editorGroup])
} }
/** Layer editor supporting multiple types of layers. */ type LayerEditorProps = {
export default class LayerEditor extends React.Component { layer: LayerSpecification
static propTypes = { sources?: SourceSpecification
layer: PropTypes.object.isRequired, vectorLayers: {[key: string]: any}
sources: PropTypes.object, spec: object
vectorLayers: PropTypes.object, onLayerChanged(...args: unknown[]): unknown
spec: PropTypes.object.isRequired, onLayerIdChange(...args: unknown[]): unknown
onLayerChanged: PropTypes.func, onMoveLayer(...args: unknown[]): unknown
onLayerIdChange: PropTypes.func, onLayerDestroy(...args: unknown[]): unknown
onMoveLayer: PropTypes.func, onLayerCopy(...args: unknown[]): unknown
onLayerDestroy: PropTypes.func, onLayerVisibilityToggle(...args: unknown[]): unknown
onLayerCopy: PropTypes.func, isFirstLayer?: boolean
onLayerVisibilityToggle: PropTypes.func, isLastLayer?: boolean
isFirstLayer: PropTypes.bool, layerIndex: number
isLastLayer: PropTypes.bool, errors?: any[]
layerIndex: PropTypes.number, };
errors: PropTypes.array,
}
type LayerEditorState = {
editorGroups: {[keys:string]: boolean}
};
/** Layer editor supporting multiple types of layers. */
export default class LayerEditor extends React.Component<LayerEditorProps, LayerEditorState> {
static defaultProps = { static defaultProps = {
onLayerChanged: () => {}, onLayerChanged: () => {},
onLayerIdChange: () => {}, onLayerIdChange: () => {},
@@ -73,11 +77,11 @@ export default class LayerEditor extends React.Component {
reactIconBase: PropTypes.object reactIconBase: PropTypes.object
} }
constructor(props) { constructor(props: LayerEditorProps) {
super(props) super(props)
//TODO: Clean this up and refactor into function //TODO: Clean this up and refactor into function
const editorGroups = {} const editorGroups: {[keys:string]: boolean} = {}
layoutGroups(this.props.layer.type).forEach(group => { layoutGroups(this.props.layer.type).forEach(group => {
editorGroups[group.title] = true editorGroups[group.title] = true
}) })
@@ -85,7 +89,7 @@ export default class LayerEditor extends React.Component {
this.state = { editorGroups } this.state = { editorGroups }
} }
static getDerivedStateFromProps(props, state) { static getDerivedStateFromProps(props: LayerEditorProps, state: LayerEditorState) {
const additionalGroups = { ...state.editorGroups } const additionalGroups = { ...state.editorGroups }
getLayoutForType(props.layer.type).groups.forEach(group => { getLayoutForType(props.layer.type).groups.forEach(group => {
@@ -108,14 +112,14 @@ export default class LayerEditor extends React.Component {
} }
} }
changeProperty(group, property, newValue) { changeProperty(group: keyof LayerSpecification | null, property: string, newValue: any) {
this.props.onLayerChanged( this.props.onLayerChanged(
this.props.layerIndex, this.props.layerIndex,
changeProperty(this.props.layer, group, property, newValue) changeProperty(this.props.layer, group, property, newValue)
) )
} }
onGroupToggle(groupTitle, active) { onGroupToggle(groupTitle: string, active: boolean) {
const changedActiveGroups = { const changedActiveGroups = {
...this.state.editorGroups, ...this.state.editorGroups,
[groupTitle]: active, [groupTitle]: active,
@@ -125,15 +129,15 @@ export default class LayerEditor extends React.Component {
}) })
} }
renderGroupType(type, fields) { renderGroupType(type: string, fields?: string[]): JSX.Element {
let comment = "" let comment = ""
if(this.props.layer.metadata) { if(this.props.layer.metadata) {
comment = this.props.layer.metadata['maputnik:comment'] comment = (this.props.layer.metadata as any)['maputnik:comment']
} }
const {errors, layerIndex} = this.props; const {errors, layerIndex} = this.props;
const errorData = {}; const errorData: {[key in LayerSpecification as string]: {message: string}} = {};
errors.forEach(error => { errors!.forEach(error => {
if ( if (
error.parsed && error.parsed &&
error.parsed.type === "layer" && error.parsed.type === "layer" &&
@@ -146,8 +150,8 @@ export default class LayerEditor extends React.Component {
}) })
let sourceLayerIds; let sourceLayerIds;
if(this.props.sources.hasOwnProperty(this.props.layer.source)) { if(this.props.sources?.hasOwnProperty((this.props.layer as Exclude<LayerSpecification, BackgroundLayerSpecification>).source)) {
sourceLayerIds = this.props.sources[this.props.layer.source].layers; sourceLayerIds = (this.props.sources as any)[(this.props.layer as any).source].layers;
} }
switch(type) { switch(type) {
@@ -169,7 +173,7 @@ export default class LayerEditor extends React.Component {
/> />
{this.props.layer.type !== 'background' && <FieldSource {this.props.layer.type !== 'background' && <FieldSource
error={errorData.source} error={errorData.source}
sourceIds={Object.keys(this.props.sources)} sourceIds={Object.keys(this.props.sources!)}
value={this.props.layer.source} value={this.props.layer.source}
onChange={v => this.changeProperty(null, 'source', v)} onChange={v => this.changeProperty(null, 'source', v)}
/> />
@@ -178,7 +182,7 @@ export default class LayerEditor extends React.Component {
<FieldSourceLayer <FieldSourceLayer
error={errorData['source-layer']} error={errorData['source-layer']}
sourceLayerIds={sourceLayerIds} sourceLayerIds={sourceLayerIds}
value={this.props.layer['source-layer']} value={(this.props.layer as any)['source-layer']}
onChange={v => this.changeProperty(null, 'source-layer', v)} onChange={v => this.changeProperty(null, 'source-layer', v)}
/> />
} }
@@ -202,8 +206,8 @@ export default class LayerEditor extends React.Component {
<div className="maputnik-filter-editor-wrapper"> <div className="maputnik-filter-editor-wrapper">
<FilterEditor <FilterEditor
errors={errorData} errors={errorData}
filter={this.props.layer.filter} filter={(this.props.layer as any).filter}
properties={this.props.vectorLayers[this.props.layer['source-layer']]} properties={this.props.vectorLayers[(this.props.layer as any)['source-layer']]}
onChange={f => this.changeProperty(null, 'filter', f)} onChange={f => this.changeProperty(null, 'filter', f)}
/> />
</div> </div>
@@ -212,7 +216,7 @@ export default class LayerEditor extends React.Component {
return <PropertyGroup return <PropertyGroup
errors={errorData} errors={errorData}
layer={this.props.layer} layer={this.props.layer}
groupFields={fields} groupFields={fields!}
spec={this.props.spec} spec={this.props.spec}
onChange={this.changeProperty.bind(this)} onChange={this.changeProperty.bind(this)}
/> />
@@ -226,10 +230,11 @@ export default class LayerEditor extends React.Component {
); );
}} }}
/> />
default: return <></>
} }
} }
moveLayer(offset) { moveLayer(offset: number) {
this.props.onMoveLayer({ this.props.onMoveLayer({
oldIndex: this.props.layerIndex, oldIndex: this.props.layerIndex,
newIndex: this.props.layerIndex+offset newIndex: this.props.layerIndex+offset
@@ -237,7 +242,7 @@ export default class LayerEditor extends React.Component {
} }
render() { render() {
const groupIds = []; const groupIds: string[] = [];
const layerType = this.props.layer.type const layerType = this.props.layer.type
const groups = layoutGroups(layerType).filter(group => { const groups = layoutGroups(layerType).filter(group => {
return !(layerType === 'background' && group.type === 'source') return !(layerType === 'background' && group.type === 'source')
@@ -258,7 +263,7 @@ export default class LayerEditor extends React.Component {
const layout = this.props.layer.layout || {} const layout = this.props.layer.layout || {}
const items = { const items: {[key: string]: {text: string, handler: () => void, disabled?: boolean}} = {
delete: { delete: {
text: "Delete", text: "Delete",
handler: () => this.props.onLayerDestroy(this.props.layerIndex) handler: () => this.props.onLayerDestroy(this.props.layerIndex)
@@ -285,8 +290,8 @@ export default class LayerEditor extends React.Component {
} }
} }
function handleSelection(id, event) { function handleSelection(id: string, event: React.SyntheticEvent) {
event.stopPropagation; event.stopPropagation();
items[id].handler(); items[id].handler();
} }
@@ -310,7 +315,7 @@ export default class LayerEditor extends React.Component {
</Button> </Button>
<Menu> <Menu>
<ul className="more-menu__menu"> <ul className="more-menu__menu">
{Object.keys(items).map((id, idx) => { {Object.keys(items).map((id) => {
const item = items[id]; const item = items[id];
return <li key={id}> return <li key={id}>
<MenuItem value={id} className='more-menu__menu__item'> <MenuItem value={id} className='more-menu__menu__item'>
+1 -1
View File
@@ -18,7 +18,7 @@ type LayerEditorGroupProps = {
title: string title: string
isActive: boolean isActive: boolean
children: React.ReactElement children: React.ReactElement
onActiveToggle(...args: unknown[]): unknown onActiveToggle(active: boolean): unknown
}; };
+1 -1
View File
@@ -39,7 +39,7 @@ type PropertyGroupProps = {
groupFields: string[] groupFields: string[]
onChange(...args: unknown[]): unknown onChange(...args: unknown[]): unknown
spec: any spec: any
errors?: unknown[] errors?: {[key: string]: {message: string}}
}; };
export default class PropertyGroup extends React.Component<PropertyGroupProps> { export default class PropertyGroup extends React.Component<PropertyGroupProps> {
+1 -1
View File
@@ -36,7 +36,7 @@ function parseFilter(v: string | boolean | number) {
type SingleFilterEditorProps = { type SingleFilterEditorProps = {
filter: any[] filter: any[]
onChange(...args: unknown[]): unknown onChange(filter: any[]): unknown
properties?: {[key: string]: string} properties?: {[key: string]: string}
}; };
+1 -1
View File
@@ -288,7 +288,7 @@ export default class DataProperty extends React.Component<DataPropertyProps, Dat
<div className="maputnik-data-spec-property-input"> <div className="maputnik-data-spec-property-input">
<InputSelect <InputSelect
value={this.props.value!.type} value={this.props.value!.type}
onChange={propVal => this.changeDataType(propVal)} onChange={(propVal: string) => this.changeDataType(propVal)}
title={"Select a type of data scale (default is 'categorical')."} title={"Select a type of data scale (default is 'categorical')."}
options={this.getDataFunctionTypes(this.props.fieldSpec)} options={this.getDataFunctionTypes(this.props.fieldSpec)}
/> />
+3 -2
View File
@@ -14,7 +14,7 @@ type ExpressionPropertyProps = {
fieldType?: string fieldType?: string
fieldSpec?: object fieldSpec?: object
value?: any value?: any
errors?: {[key: string]: any} errors?: {[key: string]: {message: string}}
onChange?(...args: unknown[]): unknown onChange?(...args: unknown[]): unknown
onUndo?(...args: unknown[]): unknown onUndo?(...args: unknown[]): unknown
canUndo?(...args: unknown[]): unknown canUndo?(...args: unknown[]): unknown
@@ -109,7 +109,8 @@ export default class ExpressionProperty extends React.Component<ExpressionProper
} }
return <Block return <Block
error={foundErrors} // this feels like an incorrect type...? `foundErrors` is an array of objects, not a single object
error={foundErrors as any}
fieldSpec={this.props.fieldSpec} fieldSpec={this.props.fieldSpec}
label={labelFromFieldName(this.props.fieldName)} label={labelFromFieldName(this.props.fieldName)}
action={deleteStopBtn} action={deleteStopBtn}
+1 -1
View File
@@ -8,7 +8,7 @@ type BlockIdProps = {
value: string value: string
wdKey: string wdKey: string
onChange(...args: unknown[]): unknown onChange(...args: unknown[]): unknown
error?: unknown[] error?: {message: string}
}; };
export default class BlockId extends React.Component<BlockIdProps> { export default class BlockId extends React.Component<BlockIdProps> {
+1 -1
View File
@@ -7,7 +7,7 @@ import FieldNumber from './FieldNumber'
type BlockMaxZoomProps = { type BlockMaxZoomProps = {
value?: number value?: number
onChange(...args: unknown[]): unknown onChange(...args: unknown[]): unknown
error?: unknown[] error?: {message: string}
}; };
export default class BlockMaxZoom extends React.Component<BlockMaxZoomProps> { export default class BlockMaxZoom extends React.Component<BlockMaxZoomProps> {
+1 -1
View File
@@ -7,7 +7,7 @@ import FieldNumber from './FieldNumber'
type BlockMinZoomProps = { type BlockMinZoomProps = {
value?: number value?: number
onChange(...args: unknown[]): unknown onChange(...args: unknown[]): unknown
error?: unknown[] error?: {message: string}
}; };
export default class BlockMinZoom extends React.Component<BlockMinZoomProps> { export default class BlockMinZoom extends React.Component<BlockMinZoomProps> {
+1 -1
View File
@@ -9,7 +9,7 @@ type BlockSourceProps = {
wdKey?: string wdKey?: string
onChange?(...args: unknown[]): unknown onChange?(...args: unknown[]): unknown
sourceIds?: unknown[] sourceIds?: unknown[]
error?: unknown[] error?: {message: string}
}; };
export default class BlockSource extends React.Component<BlockSourceProps> { export default class BlockSource extends React.Component<BlockSourceProps> {
+1 -1
View File
@@ -9,7 +9,7 @@ type BlockTypeProps = {
value: string value: string
wdKey?: string wdKey?: string
onChange(...args: unknown[]): unknown onChange(...args: unknown[]): unknown
error?: unknown[] error?: {message: string}
disabled?: boolean disabled?: boolean
}; };
+1 -1
View File
@@ -13,7 +13,7 @@ type SpecPropertyProps = SpecFieldProps & {
fieldType?: string fieldType?: string
fieldSpec?: any fieldSpec?: any
value?: any value?: any
errors?: unknown[] errors?: {[key: string]: {message: string}}
onExpressionClick?(...args: unknown[]): unknown onExpressionClick?(...args: unknown[]): unknown
}; };
+1 -1
View File
@@ -195,7 +195,7 @@ export default class ZoomProperty extends React.Component<ZoomPropertyProps, Zoo
<div className="maputnik-data-spec-property-input"> <div className="maputnik-data-spec-property-input">
<InputSelect <InputSelect
value={"interpolate"} value={"interpolate"}
onChange={propVal => this.changeDataType(propVal)} onChange={(propVal: string) => this.changeDataType(propVal)}
title={"Select a type of data scale (default is 'categorical')."} title={"Select a type of data scale (default is 'categorical')."}
options={this.getDataFunctionTypes(this.props.fieldSpec!)} options={this.getDataFunctionTypes(this.props.fieldSpec!)}
/> />
+1 -1
View File
@@ -27,7 +27,7 @@ export function changeType(layer: LayerSpecification, newType: string) {
/** A {@property} in either the paint our layout {@group} has changed /** A {@property} in either the paint our layout {@group} has changed
* to a {@newValue}. * to a {@newValue}.
*/ */
export function changeProperty(layer: LayerSpecification, group: keyof LayerSpecification, property: string, newValue: any) { export function changeProperty(layer: LayerSpecification, group: keyof LayerSpecification | null, property: string, newValue: any) {
// Remove the property if undefined // Remove the property if undefined
if(newValue === undefined) { if(newValue === undefined) {
if(group) { if(group) {