diff --git a/x-pack/plugins/maps/public/classes/styles/vector/components/legend/breaked_legend.js b/x-pack/plugins/maps/public/classes/styles/vector/components/legend/breaked_legend.tsx similarity index 69% rename from x-pack/plugins/maps/public/classes/styles/vector/components/legend/breaked_legend.js rename to x-pack/plugins/maps/public/classes/styles/vector/components/legend/breaked_legend.tsx index 7e8e6896ef9ce..9d5bf85005ae1 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/components/legend/breaked_legend.js +++ b/x-pack/plugins/maps/public/classes/styles/vector/components/legend/breaked_legend.tsx @@ -4,35 +4,59 @@ * you may not use this file except in compliance with the Elastic License. */ -import React from 'react'; +import React, { Component, ReactElement } from 'react'; import _ from 'lodash'; import { EuiFlexGroup, EuiFlexItem, EuiText, EuiToolTip } from '@elastic/eui'; import { Category } from './category'; +import { IDynamicStyleProperty } from '../../properties/dynamic_style_property'; + const EMPTY_VALUE = ''; -export class BreakedLegend extends React.Component { - state = { +interface Break { + color: string; + label: ReactElement | string; + symbolId: string; +} + +interface Props { + style: IDynamicStyleProperty; + breaks: Break[]; + isLinesOnly: boolean; + isPointsOnly: boolean; +} + +interface State { + label: string; +} + +export class BreakedLegend extends Component { + private _isMounted: boolean = false; + + state: State = { label: EMPTY_VALUE, }; componentDidMount() { this._isMounted = true; - this._loadParams(); + this._loadLabel(); } componentDidUpdate() { - this._loadParams(); + this._loadLabel(); } componentWillUnmount() { this._isMounted = false; } - async _loadParams() { - const label = await this.props.style.getField().getLabel(); - const newState = { label }; - if (this._isMounted && !_.isEqual(this.state, newState)) { - this.setState(newState); + async _loadLabel() { + const field = this.props.style.getField(); + if (!field) { + return; + } + const label = await field.getLabel(); + if (this._isMounted && !_.isEqual(this.state.label, label)) { + this.setState({ label }); } } diff --git a/x-pack/plugins/maps/public/classes/styles/vector/components/legend/category.js b/x-pack/plugins/maps/public/classes/styles/vector/components/legend/category.tsx similarity index 82% rename from x-pack/plugins/maps/public/classes/styles/vector/components/legend/category.js rename to x-pack/plugins/maps/public/classes/styles/vector/components/legend/category.tsx index cfdbd728c2217..02ca4645dd8cd 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/components/legend/category.js +++ b/x-pack/plugins/maps/public/classes/styles/vector/components/legend/category.tsx @@ -4,12 +4,21 @@ * you may not use this file except in compliance with the Elastic License. */ -import React from 'react'; -import { VECTOR_STYLES } from '../../../../../../common/constants'; +import React, { ReactElement } from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui'; +import { VECTOR_STYLES } from '../../../../../../common/constants'; import { VectorIcon } from './vector_icon'; -export function Category({ styleName, label, color, isLinesOnly, isPointsOnly, symbolId }) { +interface Props { + styleName: VECTOR_STYLES; + label: ReactElement | string; + color: string; + isLinesOnly: boolean; + isPointsOnly: boolean; + symbolId: string; +} + +export function Category({ styleName, label, color, isLinesOnly, isPointsOnly, symbolId }: Props) { function renderIcon() { if (styleName === VECTOR_STYLES.LABEL_COLOR) { return ( diff --git a/x-pack/plugins/maps/public/classes/styles/vector/components/legend/circle_icon.js b/x-pack/plugins/maps/public/classes/styles/vector/components/legend/circle_icon.tsx similarity index 92% rename from x-pack/plugins/maps/public/classes/styles/vector/components/legend/circle_icon.js rename to x-pack/plugins/maps/public/classes/styles/vector/components/legend/circle_icon.tsx index 5efba64360f23..0056a2cba02cd 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/components/legend/circle_icon.js +++ b/x-pack/plugins/maps/public/classes/styles/vector/components/legend/circle_icon.tsx @@ -4,9 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import React from 'react'; +import React, { CSSProperties } from 'react'; -export const CircleIcon = ({ style }) => ( +export const CircleIcon = ({ style }: { style: CSSProperties }) => ( ( +export const LineIcon = ({ style }: { style: CSSProperties }) => ( diff --git a/x-pack/plugins/maps/public/classes/styles/vector/components/legend/ordinal_legend.js b/x-pack/plugins/maps/public/classes/styles/vector/components/legend/ordinal_legend.tsx similarity index 70% rename from x-pack/plugins/maps/public/classes/styles/vector/components/legend/ordinal_legend.js rename to x-pack/plugins/maps/public/classes/styles/vector/components/legend/ordinal_legend.tsx index 478d96962e47b..1683a1ae141ca 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/components/legend/ordinal_legend.js +++ b/x-pack/plugins/maps/public/classes/styles/vector/components/legend/ordinal_legend.tsx @@ -4,12 +4,14 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { Fragment } from 'react'; +import React, { Component, Fragment } from 'react'; import _ from 'lodash'; +// @ts-expect-error +import { EuiFlexGroup, EuiFlexItem, EuiHorizontalRule } from '@elastic/eui'; import { RangedStyleLegendRow } from '../../../components/ranged_style_legend_row'; import { VECTOR_STYLES } from '../../../../../../common/constants'; -import { EuiFlexGroup, EuiFlexItem, EuiHorizontalRule } from '@elastic/eui'; import { CircleIcon } from './circle_icon'; +import { IDynamicStyleProperty } from '../../properties/dynamic_style_property'; function getLineWidthIcons() { const defaultStyle = { @@ -37,41 +39,50 @@ function getSymbolSizeIcons() { } const EMPTY_VALUE = ''; -export class OrdinalLegend extends React.Component { - constructor() { - super(); - this._isMounted = false; - this.state = { - label: EMPTY_VALUE, - }; - } +interface Props { + style: IDynamicStyleProperty; +} - async _loadParams() { - const label = await this.props.style.getField().getLabel(); - const newState = { label }; - if (this._isMounted && !_.isEqual(this.state, newState)) { - this.setState(newState); - } - } +interface State { + label: string; +} - _formatValue(value) { - if (value === EMPTY_VALUE) { - return value; - } - return this.props.style.formatField(value); +export class OrdinalLegend extends Component { + private _isMounted: boolean = false; + + state: State = { + label: EMPTY_VALUE, + }; + + componentDidMount() { + this._isMounted = true; + this._loadLabel(); } componentDidUpdate() { - this._loadParams(); + this._loadLabel(); } componentWillUnmount() { this._isMounted = false; } - componentDidMount() { - this._isMounted = true; - this._loadParams(); + async _loadLabel() { + const field = this.props.style.getField(); + if (!field) { + return; + } + const label = await field.getLabel(); + if (this._isMounted && !_.isEqual(this.state.label, label)) { + this.setState({ label }); + } + } + + _formatValue(value: string | number) { + if (value === EMPTY_VALUE) { + return value; + } + return this.props.style.formatField(value); } _renderRangeLegendHeader() { @@ -115,21 +126,16 @@ export class OrdinalLegend extends React.Component { const fieldMeta = this.props.style.getRangeFieldMeta(); - let minLabel = EMPTY_VALUE; - let maxLabel = EMPTY_VALUE; + let minLabel: string | number = EMPTY_VALUE; + let maxLabel: string | number = EMPTY_VALUE; if (fieldMeta) { - const range = { min: fieldMeta.min, max: fieldMeta.max }; - const min = this._formatValue(_.get(range, 'min', EMPTY_VALUE)); + const min = this._formatValue(_.get(fieldMeta, 'min', EMPTY_VALUE)); minLabel = - this.props.style.isFieldMetaEnabled() && range && range.isMinOutsideStdRange - ? `< ${min}` - : min; + this.props.style.isFieldMetaEnabled() && fieldMeta.isMinOutsideStdRange ? `< ${min}` : min; - const max = this._formatValue(_.get(range, 'max', EMPTY_VALUE)); + const max = this._formatValue(_.get(fieldMeta, 'max', EMPTY_VALUE)); maxLabel = - this.props.style.isFieldMetaEnabled() && range && range.isMaxOutsideStdRange - ? `> ${max}` - : max; + this.props.style.isFieldMetaEnabled() && fieldMeta.isMaxOutsideStdRange ? `> ${max}` : max; } return ( diff --git a/x-pack/plugins/maps/public/classes/styles/vector/components/legend/polygon_icon.js b/x-pack/plugins/maps/public/classes/styles/vector/components/legend/polygon_icon.tsx similarity index 78% rename from x-pack/plugins/maps/public/classes/styles/vector/components/legend/polygon_icon.js rename to x-pack/plugins/maps/public/classes/styles/vector/components/legend/polygon_icon.tsx index 4210b59f0d676..09241d538a0fe 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/components/legend/polygon_icon.js +++ b/x-pack/plugins/maps/public/classes/styles/vector/components/legend/polygon_icon.tsx @@ -4,9 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import React from 'react'; +import React, { CSSProperties } from 'react'; -export const PolygonIcon = ({ style }) => ( +export const PolygonIcon = ({ style }: { style: CSSProperties }) => ( diff --git a/x-pack/plugins/maps/public/classes/styles/vector/components/legend/symbol_icon.js b/x-pack/plugins/maps/public/classes/styles/vector/components/legend/symbol_icon.tsx similarity index 83% rename from x-pack/plugins/maps/public/classes/styles/vector/components/legend/symbol_icon.js rename to x-pack/plugins/maps/public/classes/styles/vector/components/legend/symbol_icon.tsx index ea3886c600be9..c5d41ae2b1a9b 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/components/legend/symbol_icon.js +++ b/x-pack/plugins/maps/public/classes/styles/vector/components/legend/symbol_icon.tsx @@ -5,13 +5,24 @@ */ import React, { Component } from 'react'; -import PropTypes from 'prop-types'; - +// @ts-expect-error import { getMakiSymbolSvg, styleSvg, buildSrcUrl } from '../../symbol_utils'; -export class SymbolIcon extends Component { - state = { - imgDataUrl: undefined, +interface Props { + symbolId: string; + fill?: string; + stroke?: string; +} + +interface State { + imgDataUrl: string | null; +} + +export class SymbolIcon extends Component { + private _isMounted: boolean = false; + + state: State = { + imgDataUrl: null, }; componentDidMount() { @@ -62,9 +73,3 @@ export class SymbolIcon extends Component { ); } } - -SymbolIcon.propTypes = { - symbolId: PropTypes.string.isRequired, - fill: PropTypes.string, - stroke: PropTypes.string, -}; diff --git a/x-pack/plugins/maps/public/classes/styles/vector/components/legend/vector_icon.test.js b/x-pack/plugins/maps/public/classes/styles/vector/components/legend/vector_icon.test.tsx similarity index 100% rename from x-pack/plugins/maps/public/classes/styles/vector/components/legend/vector_icon.test.js rename to x-pack/plugins/maps/public/classes/styles/vector/components/legend/vector_icon.test.tsx diff --git a/x-pack/plugins/maps/public/classes/styles/vector/components/legend/vector_icon.js b/x-pack/plugins/maps/public/classes/styles/vector/components/legend/vector_icon.tsx similarity index 79% rename from x-pack/plugins/maps/public/classes/styles/vector/components/legend/vector_icon.js rename to x-pack/plugins/maps/public/classes/styles/vector/components/legend/vector_icon.tsx index e255dceda856e..d68bbdae2c17e 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/components/legend/vector_icon.js +++ b/x-pack/plugins/maps/public/classes/styles/vector/components/legend/vector_icon.tsx @@ -5,14 +5,21 @@ */ import React from 'react'; -import PropTypes from 'prop-types'; import { CircleIcon } from './circle_icon'; import { LineIcon } from './line_icon'; import { PolygonIcon } from './polygon_icon'; import { SymbolIcon } from './symbol_icon'; -export function VectorIcon({ fillColor, isPointsOnly, isLinesOnly, strokeColor, symbolId }) { +interface Props { + fillColor?: string; + isPointsOnly: boolean; + isLinesOnly: boolean; + strokeColor?: string; + symbolId?: string; +} + +export function VectorIcon({ fillColor, isPointsOnly, isLinesOnly, strokeColor, symbolId }: Props) { if (isLinesOnly) { const style = { stroke: strokeColor, @@ -44,11 +51,3 @@ export function VectorIcon({ fillColor, isPointsOnly, isLinesOnly, strokeColor, /> ); } - -VectorIcon.propTypes = { - fillColor: PropTypes.string, - isPointsOnly: PropTypes.bool.isRequired, - isLinesOnly: PropTypes.bool.isRequired, - strokeColor: PropTypes.string, - symbolId: PropTypes.string, -}; diff --git a/x-pack/plugins/maps/public/classes/styles/vector/components/legend/vector_style_legend.js b/x-pack/plugins/maps/public/classes/styles/vector/components/legend/vector_style_legend.tsx similarity index 74% rename from x-pack/plugins/maps/public/classes/styles/vector/components/legend/vector_style_legend.js rename to x-pack/plugins/maps/public/classes/styles/vector/components/legend/vector_style_legend.tsx index 88eb4109627e5..4d50c632bfd6d 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/components/legend/vector_style_legend.js +++ b/x-pack/plugins/maps/public/classes/styles/vector/components/legend/vector_style_legend.tsx @@ -5,8 +5,16 @@ */ import React from 'react'; +import { IStyleProperty } from '../../properties/style_property'; -export function VectorStyleLegend({ isLinesOnly, isPointsOnly, styles, symbolId }) { +interface Props { + isLinesOnly: boolean; + isPointsOnly: boolean; + styles: Array>; + symbolId: string; +} + +export function VectorStyleLegend({ isLinesOnly, isPointsOnly, styles, symbolId }: Props) { const legendRows = []; for (let i = 0; i < styles.length; i++) { diff --git a/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_icon_property.js b/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_icon_property.tsx similarity index 80% rename from x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_icon_property.js rename to x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_icon_property.tsx index 665317569e5e8..f0309952f43a3 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_icon_property.js +++ b/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_icon_property.tsx @@ -6,13 +6,18 @@ import _ from 'lodash'; import React from 'react'; +import { EuiTextColor } from '@elastic/eui'; +import { Map as MbMap } from 'mapbox-gl'; import { DynamicStyleProperty } from './dynamic_style_property'; +// @ts-expect-error import { getIconPalette, getMakiIconId, getMakiSymbolAnchor } from '../symbol_utils'; import { BreakedLegend } from '../components/legend/breaked_legend'; import { getOtherCategoryLabel, assignCategoriesToPalette } from '../style_util'; -import { EuiTextColor } from '@elastic/eui'; +import { LegendProps } from './style_property'; -export class DynamicIconProperty extends DynamicStyleProperty { +export class DynamicIconProperty extends DynamicStyleProperty< + IconDynamicOptions +> { isOrdinal() { return false; } @@ -26,7 +31,7 @@ export class DynamicIconProperty extends DynamicStyleProperty { return palette.length; } - syncIconWithMb(symbolLayerId, mbMap, iconPixelSize) { + syncIconWithMb(symbolLayerId: string, mbMap: MbMap, iconPixelSize: number) { if (this._isIconDynamicConfigComplete()) { mbMap.setLayoutProperty( symbolLayerId, @@ -64,11 +69,11 @@ export class DynamicIconProperty extends DynamicStyleProperty { }); } - _getMbIconImageExpression(iconPixelSize) { + _getMbIconImageExpression(iconPixelSize: number) { const { stops, fallbackSymbolId } = this._getPaletteStops(); if (stops.length < 1 || !fallbackSymbolId) { - //occurs when no data + // occurs when no data return null; } @@ -79,16 +84,16 @@ export class DynamicIconProperty extends DynamicStyleProperty { }); if (fallbackSymbolId) { - mbStops.push(getMakiIconId(fallbackSymbolId, iconPixelSize)); //last item is fallback style for anything that does not match provided stops + mbStops.push(getMakiIconId(fallbackSymbolId, iconPixelSize)); // last item is fallback style for anything that does not match provided stops } - return ['match', ['to-string', ['get', this._field.getName()]], ...mbStops]; + return ['match', ['to-string', ['get', this.getFieldName()]], ...mbStops]; } _getMbIconAnchorExpression() { const { stops, fallbackSymbolId } = this._getPaletteStops(); if (stops.length < 1 || !fallbackSymbolId) { - //occurs when no data + // occurs when no data return null; } @@ -99,16 +104,16 @@ export class DynamicIconProperty extends DynamicStyleProperty { }); if (fallbackSymbolId) { - mbStops.push(getMakiSymbolAnchor(fallbackSymbolId)); //last item is fallback style for anything that does not match provided stops + mbStops.push(getMakiSymbolAnchor(fallbackSymbolId)); // last item is fallback style for anything that does not match provided stops } - return ['match', ['to-string', ['get', this._field.getName()]], ...mbStops]; + return ['match', ['to-string', ['get', this.getFieldName()]], ...mbStops]; } _isIconDynamicConfigComplete() { return this._field && this._field.isValid(); } - renderLegendDetailRow({ isPointsOnly, isLinesOnly }) { + renderLegendDetailRow({ isPointsOnly, isLinesOnly }: LegendProps) { const { stops, fallbackSymbolId } = this._getPaletteStops(); const breaks = []; stops.forEach(({ stop, style }) => { diff --git a/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_style_property.tsx b/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_style_property.tsx index 216fde595af32..f666a9aad7804 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_style_property.tsx +++ b/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_style_property.tsx @@ -46,7 +46,7 @@ export interface IDynamicStyleProperty extends IStyleProperty { getValueSuggestions(query: string): Promise; } -type fieldFormatter = (value: string | undefined) => string; +type fieldFormatter = (value: string | number | undefined) => string | number; export class DynamicStyleProperty extends AbstractStyleProperty implements IDynamicStyleProperty { @@ -69,12 +69,10 @@ export class DynamicStyleProperty extends AbstractStyleProperty this._getFieldFormatter = getFieldFormatter; } - // ignore TS error about "Type '(query: string) => Promise | never[]' is not assignable to type '(query: string) => Promise'." - // @ts-expect-error - getValueSuggestions = (query: string) => { + getValueSuggestions = async (query: string) => { return this._field === null ? [] - : this._field.getSource().getValueSuggestions(this._field, query); + : await this._field.getSource().getValueSuggestions(this._field, query); }; _getStyleMetaDataRequestId(fieldName: string) { @@ -306,7 +304,7 @@ export class DynamicStyleProperty extends AbstractStyleProperty }; } - formatField(value: string | undefined): string { + formatField(value: string | number | undefined): string | number { if (this.getField()) { const fieldName = this.getFieldName(); const fieldFormatter = this._getFieldFormatter(fieldName); @@ -316,10 +314,6 @@ export class DynamicStyleProperty extends AbstractStyleProperty } } - renderLegendDetailRow() { - return null; - } - renderFieldMetaPopover(onFieldMetaOptionsChange: (fieldMetaOptions: FieldMetaOptions) => void) { if (!this.supportsFieldMeta()) { return null; diff --git a/x-pack/plugins/maps/public/classes/styles/vector/properties/style_property.ts b/x-pack/plugins/maps/public/classes/styles/vector/properties/style_property.ts index 7a0ed4fb3e962..ec52f6a0f7283 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/properties/style_property.ts +++ b/x-pack/plugins/maps/public/classes/styles/vector/properties/style_property.ts @@ -11,7 +11,7 @@ import { getVectorStyleLabel } from '../components/get_vector_style_label'; import { FieldMetaOptions } from '../../../../../common/descriptor_types'; import { VECTOR_STYLES } from '../../../../../common/constants'; -type LegendProps = { +export type LegendProps = { isPointsOnly: boolean; isLinesOnly: boolean; symbolId?: string; @@ -20,7 +20,7 @@ type LegendProps = { export interface IStyleProperty { isDynamic(): boolean; isComplete(): boolean; - formatField(value: string | undefined): string; + formatField(value: string | number | undefined): string | number; getStyleName(): VECTOR_STYLES; getOptions(): T; renderLegendDetailRow(legendProps: LegendProps): ReactElement | null; @@ -53,7 +53,7 @@ export class AbstractStyleProperty implements IStyleProperty { return true; } - formatField(value: string | undefined): string { + formatField(value: string | number | undefined): string | number { // eslint-disable-next-line eqeqeq return value == undefined ? '' : value; } @@ -66,7 +66,7 @@ export class AbstractStyleProperty implements IStyleProperty { return this._options; } - renderLegendDetailRow() { + renderLegendDetailRow({ isPointsOnly, isLinesOnly }: LegendProps): ReactElement | null { return null; } diff --git a/x-pack/plugins/maps/public/routing/routes/maps_app/maps_app_view.js b/x-pack/plugins/maps/public/routing/routes/maps_app/maps_app_view.js index d945aa9623b21..63582ce1ed27f 100644 --- a/x-pack/plugins/maps/public/routing/routes/maps_app/maps_app_view.js +++ b/x-pack/plugins/maps/public/routing/routes/maps_app/maps_app_view.js @@ -124,7 +124,7 @@ export class MapsAppView extends React.Component { return; } - this._onQueryChange({ time: globalState.time, refresh: true }); + this._onQueryChange({ time: globalState.time, refresh: false }); }; async _updateIndexPatterns() {