mirror of https://github.com/grafana/grafana.git
127 lines
3.8 KiB
TypeScript
127 lines
3.8 KiB
TypeScript
import { useCallback, useMemo } from 'react';
|
|
|
|
import { SelectableValue, StandardEditorContext } from '@grafana/data';
|
|
import { useTranslate } from '@grafana/i18n';
|
|
import { InlineFieldRow, InlineField, RadioButtonGroup, Select } from '@grafana/ui';
|
|
import { NumberInput } from 'app/core/components/OptionsUI/NumberInput';
|
|
|
|
import { GeomapInstanceState, Options, MapViewConfig } from '../types';
|
|
|
|
type Props = {
|
|
labelWidth: number;
|
|
value: MapViewConfig;
|
|
onChange: (value?: MapViewConfig | undefined) => void;
|
|
context: StandardEditorContext<Options, GeomapInstanceState>;
|
|
};
|
|
|
|
// Data scope options for 'Fit to data'
|
|
enum DataScopeValues {
|
|
all = 'all',
|
|
layer = 'layer',
|
|
last = 'last',
|
|
}
|
|
enum DataScopeLabels {
|
|
all = 'All layers',
|
|
layer = 'Layer',
|
|
last = 'Last value',
|
|
}
|
|
|
|
const ScopeOptions = Object.values(DataScopeValues);
|
|
|
|
const DataScopeOptions: Array<SelectableValue<DataScopeValues>> = ScopeOptions.map((dataScopeOption) => ({
|
|
label: DataScopeLabels[dataScopeOption],
|
|
value: dataScopeOption,
|
|
}));
|
|
|
|
export const FitMapViewEditor = ({ labelWidth, value, onChange, context }: Props) => {
|
|
const { t } = useTranslate();
|
|
const layers = useMemo(() => {
|
|
if (context.options?.layers) {
|
|
return context.options.layers.map((layer) => ({
|
|
label: layer.name,
|
|
value: layer.name,
|
|
description: undefined,
|
|
}));
|
|
}
|
|
return [];
|
|
}, [context.options?.layers]);
|
|
|
|
const onSelectLayer = useCallback(
|
|
(selection: SelectableValue<string>) => {
|
|
onChange({ ...value, layer: selection.value });
|
|
},
|
|
[value, onChange]
|
|
);
|
|
|
|
const allLayersEditorFragment = (
|
|
<InlineFieldRow>
|
|
<InlineField
|
|
label={t('geomap.fit-map-view-editor.all-layers-editor-fragment.label-layer', 'Layer')}
|
|
labelWidth={labelWidth}
|
|
grow={true}
|
|
>
|
|
<Select options={layers} onChange={onSelectLayer} placeholder={layers[0]?.label} value={value.layer} />
|
|
</InlineField>
|
|
</InlineFieldRow>
|
|
);
|
|
|
|
const onChangePadding = (padding: number | undefined) => {
|
|
onChange({ ...value, padding: padding });
|
|
};
|
|
|
|
const lastOnlyEditorFragment = (
|
|
<InlineFieldRow>
|
|
<InlineField
|
|
label={t('geomap.fit-map-view-editor.last-only-editor-fragment.label-padding', 'Padding')}
|
|
labelWidth={labelWidth}
|
|
grow={true}
|
|
tooltip={t(
|
|
'geomap.fit-map-view-editor.last-only-editor-fragment.tooltip-padding-relative-percent-beyond-extent',
|
|
'Sets padding in relative percent beyond data extent'
|
|
)}
|
|
>
|
|
<NumberInput value={value?.padding ?? 5} min={0} step={1} onChange={onChangePadding} />
|
|
</InlineField>
|
|
</InlineFieldRow>
|
|
);
|
|
|
|
const currentDataScope = value.allLayers
|
|
? DataScopeValues.all
|
|
: !value.allLayers && value.lastOnly
|
|
? DataScopeValues.last
|
|
: DataScopeValues.layer;
|
|
|
|
const onDataScopeChange = (dataScope: DataScopeValues) => {
|
|
if (dataScope !== DataScopeValues.all && !value.layer) {
|
|
onChange({
|
|
...value,
|
|
allLayers: dataScope === String(DataScopeValues.all),
|
|
lastOnly: dataScope === String(DataScopeValues.last),
|
|
layer: layers[0].value,
|
|
});
|
|
} else {
|
|
onChange({
|
|
...value,
|
|
allLayers: dataScope === String(DataScopeValues.all),
|
|
lastOnly: dataScope === String(DataScopeValues.last),
|
|
});
|
|
}
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<InlineFieldRow>
|
|
<InlineField label={t('geomap.fit-map-view-editor.label-data', 'Data')} labelWidth={labelWidth} grow={true}>
|
|
<RadioButtonGroup
|
|
value={currentDataScope}
|
|
options={DataScopeOptions}
|
|
onChange={onDataScopeChange}
|
|
></RadioButtonGroup>
|
|
</InlineField>
|
|
</InlineFieldRow>
|
|
{!value?.allLayers && allLayersEditorFragment}
|
|
{!value?.lastOnly && lastOnlyEditorFragment}
|
|
</>
|
|
);
|
|
};
|