import { css } from '@emotion/css'; import { FeatureLike } from 'ol/Feature'; import React, { FC, useCallback, useMemo } from 'react'; import { useObservable } from 'react-use'; import { Observable } from 'rxjs'; import { GrafanaTheme2, SelectableValue, StandardEditorProps, StandardEditorsRegistryItem } from '@grafana/data'; import { Button, InlineField, InlineFieldRow, Select, useStyles2 } from '@grafana/ui'; import { NumberInput } from 'app/core/components/OptionsUI/NumberInput'; import { DEFAULT_STYLE_RULE } from '../layers/data/geojsonLayer'; import { defaultStyleConfig, StyleConfig } from '../style/types'; import { ComparisonOperation, FeatureStyleConfig } from '../types'; import { getUniqueFeatureValues, LayerContentInfo } from '../utils/getFeatures'; import { getSelectionInfo } from '../utils/selection'; import { StyleEditor } from './StyleEditor'; export interface StyleRuleEditorSettings { features: Observable; layerInfo: Observable; } const comparators = [ { label: '==', value: ComparisonOperation.EQ }, { label: '!=', value: ComparisonOperation.NEQ }, { label: '>', value: ComparisonOperation.GT }, { label: '>=', value: ComparisonOperation.GTE }, { label: '<', value: ComparisonOperation.LT }, { label: '<=', value: ComparisonOperation.LTE }, ]; export const StyleRuleEditor: FC> = ( props ) => { const { value, onChange, item, context } = props; const settings: StyleRuleEditorSettings = item.settings; const { features, layerInfo } = settings; const propertyOptions = useObservable(layerInfo); const feats = useObservable(features); const uniqueSelectables = useMemo(() => { const key = value?.check?.property; if (key && feats && value.check?.operation === ComparisonOperation.EQ) { return getUniqueFeatureValues(feats, key).map((v) => { let newValue; let isNewValueNumber = !isNaN(Number(v)); if (isNewValueNumber) { newValue = { value: Number(v), label: v, }; } else { newValue = { value: v, label: v }; } return newValue; }); } return []; }, [feats, value]); const styles = useStyles2(getStyles); const LABEL_WIDTH = 10; const onChangeProperty = useCallback( (selection?: SelectableValue) => { onChange({ ...value, check: { ...value.check!, property: selection?.value, }, }); }, [onChange, value] ); const onChangeComparison = useCallback( (selection: SelectableValue) => { onChange({ ...value, check: { ...value.check!, operation: selection.value ?? ComparisonOperation.EQ, }, }); }, [onChange, value] ); const onChangeValue = useCallback( (selection?: SelectableValue) => { onChange({ ...value, check: { ...value.check!, value: selection?.value, }, }); }, [onChange, value] ); const onChangeNumericValue = useCallback( (v?: number) => { onChange({ ...value, check: { ...value.check!, value: v!, }, }); }, [onChange, value] ); const onChangeStyle = useCallback( (style?: StyleConfig) => { onChange({ ...value, style }); }, [onChange, value] ); const onDelete = useCallback(() => { onChange(undefined); }, [onChange]); const check = value.check ?? DEFAULT_STYLE_RULE.check!; const propv = getSelectionInfo(check.property, propertyOptions?.propertes); const valuev = getSelectionInfo(check.value, uniqueSelectables); return (
v.value === check.operation)} options={comparators} onChange={onChangeComparison} aria-label={'Comparison operator'} width={8} />
{(check.operation === ComparisonOperation.EQ || check.operation === ComparisonOperation.NEQ) && (