Skip to content

Commit

Permalink
[Vis: Default editor] EUIficate region map options tab (#42944) (#43393)
Browse files Browse the repository at this point in the history
* EUIficate region_map_options

* Reuse types

* Remove wms_options directive

* Remove style import

* Fix issue with join field default value

# Conflicts:
#	src/legacy/core_plugins/region_map/public/region_map_vis_params.html
  • Loading branch information
sulemanof authored Aug 16, 2019
1 parent bf19b19 commit 39ca6bd
Show file tree
Hide file tree
Showing 25 changed files with 447 additions and 633 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import React from 'react';
import { EuiFormRow, EuiFieldNumber } from '@elastic/eui';

interface NumberInputOptionProps<ParamName extends string> {
label?: React.ReactNode;
max?: number;
min?: number;
paramName: ParamName;
value?: number | '';
setValue: (paramName: ParamName, value: number | '') => void;
}

function NumberInputOption<ParamName extends string>({
label,
max,
min,
paramName,
value = '',
setValue,
}: NumberInputOptionProps<ParamName>) {
return (
<EuiFormRow label={label} fullWidth compressed>
<EuiFieldNumber
fullWidth
max={max}
min={min}
value={value}
onChange={ev =>
setValue(paramName, isNaN(ev.target.valueAsNumber) ? '' : ev.target.valueAsNumber)
}
/>
</EuiFormRow>
);
}

export { NumberInputOption };
Original file line number Diff line number Diff line change
Expand Up @@ -23,26 +23,29 @@ import { EuiFormRow, EuiSelect } from '@elastic/eui';
interface SelectOptionProps<ParamName extends string, ValidParamValues extends string> {
id?: string;
label: string;
labelAppend?: React.ReactNode;
options: Array<{ value: ValidParamValues; text: string }>;
paramName: ParamName;
value?: ValidParamValues;
dataTestSubj?: string;
setValue: (paramName: ParamName, value: ValidParamValues) => void;
}

const emptyValue = { text: '', value: 'EMPTY_VALUE', disabled: true, hidden: true };

function SelectOption<ParamName extends string, ValidParamValues extends string>({
id,
label,
labelAppend,
options,
paramName,
value,
setValue,
}: SelectOptionProps<ParamName, ValidParamValues>) {
return (
<EuiFormRow id={id} label={label} fullWidth={true} compressed>
<EuiFormRow id={id} label={label} fullWidth={true} compressed labelAppend={labelAppend}>
<EuiSelect
options={options}
value={value}
options={[emptyValue, ...options]}
value={value || emptyValue.value}
onChange={ev => setValue(paramName, ev.target.value as ValidParamValues)}
fullWidth={true}
/>
Expand Down
1 change: 0 additions & 1 deletion src/legacy/core_plugins/region_map/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ const regionMapPluginInitializer: LegacyPluginInitializer = ({ Plugin }: LegacyP
require: ['kibana', 'elasticsearch', 'visualizations', 'interpreter', 'data'],
publicDir: resolve(__dirname, 'public'),
uiExports: {
styleSheetPaths: resolve(__dirname, 'public/index.scss'),
hacks: [resolve(__dirname, 'public/legacy')],
injectDefaultVars(server) {
const { regionmap } = server.config().get('map');
Expand Down
4 changes: 0 additions & 4 deletions src/legacy/core_plugins/region_map/public/_region_map.scss

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,266 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import React, { useEffect, useState, useCallback, useMemo } from 'react';
import { EuiIcon, EuiLink, EuiPanel, EuiSpacer, EuiText, EuiTitle } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';

import { toastNotifications } from 'ui/notify';
import { FileLayerField, VectorLayer, ServiceSettings } from 'ui/vis/map/service_settings';
import { VisOptionsProps } from 'ui/vis/editors/default';
import { SelectOption } from '../../../kbn_vislib_vis_types/public/controls/select';
import { SwitchOption } from '../../../kbn_vislib_vis_types/public/controls/switch';
import { NumberInputOption } from '../../../kbn_vislib_vis_types/public/controls/number_input';
import { ORIGIN } from '../../../tile_map/common/origin';
import { WmsOptions } from '../../../tile_map/public/components/wms_options';
import { mapToLayerWithId } from '../util';
import { RegionMapVisParams } from '../types';
import { RegionMapsConfig } from '../plugin';

const mapLayerForOption = ({ layerId, name }: VectorLayer) => ({
text: name,
value: layerId,
});

const mapFieldForOption = ({ description, name }: FileLayerField) => ({
text: description,
value: name,
});

export type RegionMapOptionsProps = {
serviceSettings: ServiceSettings;
includeElasticMapsService: RegionMapsConfig['includeElasticMapsService'];
} & VisOptionsProps<RegionMapVisParams>;

function RegionMapOptions(props: RegionMapOptionsProps) {
const { includeElasticMapsService, serviceSettings, stateParams, vis, setValue } = props;
const [vectorLayers, setVectorLayers] = useState<VectorLayer[]>(
vis.type.editorConfig.collections.vectorLayers
);
const [vectorLayerOptions, setVectorLayerOptions] = useState(vectorLayers.map(mapLayerForOption));
const currentLayerId = stateParams.selectedLayer && stateParams.selectedLayer.layerId;
const fieldOptions = useMemo(
() =>
((stateParams.selectedLayer && stateParams.selectedLayer.fields) || []).map(
mapFieldForOption
),
[currentLayerId]
);

const setEmsHotLink = useCallback(
async (layer: VectorLayer) => {
const emsHotLink = await serviceSettings.getEMSHotLink(layer);
setValue('emsHotLink', emsHotLink);
},
[setValue]
);

const setLayer = useCallback(
async (paramName: 'selectedLayer', value: VectorLayer['layerId']) => {
const newLayer = vectorLayers.find(({ layerId }: VectorLayer) => layerId === value);

if (newLayer) {
setValue(paramName, newLayer);
setValue('selectedJoinField', newLayer.fields[0]);
setEmsHotLink(newLayer);
}
},
[vectorLayers, setValue]
);

const setField = useCallback(
(paramName: 'selectedJoinField', value: FileLayerField['name']) => {
if (stateParams.selectedLayer) {
setValue(paramName, stateParams.selectedLayer.fields.find(f => f.name === value));
}
},
[currentLayerId, setValue]
);

useEffect(() => {
async function setDefaultValues() {
try {
const layers = await serviceSettings.getFileLayers();
const newLayers = layers
.map(mapToLayerWithId.bind(null, ORIGIN.EMS))
.filter(
layer => !vectorLayers.some(vectorLayer => vectorLayer.layerId === layer.layerId)
);

// backfill v1 manifest for now
newLayers.forEach(layer => {
if (layer.format === 'geojson') {
layer.format = {
type: 'geojson',
};
}
});

const newVectorLayers = [...vectorLayers, ...newLayers];

setVectorLayers(newVectorLayers);
setVectorLayerOptions(newVectorLayers.map(mapLayerForOption));

const [newLayer] = newVectorLayers;

if (newLayer && !stateParams.selectedLayer) {
setValue('selectedLayer', newLayer);
setValue('selectedJoinField', newLayer.fields[0]);

if (newLayer.isEMS) {
setEmsHotLink(newLayer);
}
}
} catch (error) {
toastNotifications.addWarning(error.message);
}
}

if (includeElasticMapsService) {
setDefaultValues();
}
}, []);

return (
<>
<EuiPanel paddingSize="s">
<EuiTitle size="xs">
<h2>
<FormattedMessage
id="regionMap.visParams.layerSettingsTitle"
defaultMessage="Layer settings"
/>
</h2>
</EuiTitle>
<EuiSpacer size="s" />

<SelectOption
id="regionMapOptionsSelectLayer"
label={i18n.translate('regionMap.visParams.vectorMapLabel', {
defaultMessage: 'Vector map',
})}
labelAppend={
stateParams.emsHotLink && (
<EuiText size="xs">
<EuiLink
href={stateParams.emsHotLink}
target="_blank"
title={i18n.translate('regionMap.visParams.previewOnEMSLinkTitle', {
defaultMessage: 'Preview {selectedLayerName} on the Elastic Maps Service',
values: {
selectedLayerName:
stateParams.selectedLayer && stateParams.selectedLayer.name,
},
})}
>
<FormattedMessage
id="regionMap.visParams.previewOnEMSLinkText"
defaultMessage="Preview on EMS"
/>{' '}
<EuiIcon type="popout" size="s" />
</EuiLink>
</EuiText>
)
}
options={vectorLayerOptions}
paramName="selectedLayer"
value={stateParams.selectedLayer && stateParams.selectedLayer.layerId}
setValue={setLayer}
/>

<SelectOption
id="regionMapOptionsSelectJoinField"
label={i18n.translate('regionMap.visParams.joinFieldLabel', {
defaultMessage: 'Join field',
})}
options={fieldOptions}
paramName="selectedJoinField"
value={stateParams.selectedJoinField && stateParams.selectedJoinField.name}
setValue={setField}
/>

<SwitchOption
label={i18n.translate('regionMap.visParams.displayWarningsLabel', {
defaultMessage: 'Display warnings',
})}
tooltip={i18n.translate('regionMap.visParams.switchWarningsTipText', {
defaultMessage:
'Turns on/off warnings. When turned on, warning will be shown for each term that cannot be matched to a shape in the vector layer based on the join field. When turned off, these warnings will be turned off.',
})}
paramName="isDisplayWarning"
value={stateParams.isDisplayWarning}
setValue={setValue}
/>

<SwitchOption
label={i18n.translate('regionMap.visParams.showAllShapesLabel', {
defaultMessage: 'Show all shapes',
})}
tooltip={i18n.translate('regionMap.visParams.turnOffShowingAllShapesTipText', {
defaultMessage:
'Turning this off only shows the shapes that were matched with a corresponding term.',
})}
paramName="showAllShapes"
value={stateParams.showAllShapes}
setValue={setValue}
/>
</EuiPanel>

<EuiSpacer size="s" />

<EuiPanel paddingSize="s">
<EuiTitle size="xs">
<h2>
<FormattedMessage
id="regionMap.visParams.styleSettingsLabel"
defaultMessage="Style settings"
/>
</h2>
</EuiTitle>
<EuiSpacer size="s" />

<SelectOption
label={i18n.translate('regionMap.visParams.colorSchemaLabel', {
defaultMessage: 'Color schema',
})}
options={vis.type.editorConfig.collections.colorSchemas}
paramName="colorSchema"
value={stateParams.colorSchema}
setValue={setValue}
/>

<NumberInputOption
label={i18n.translate('regionMap.visParams.outlineWeightLabel', {
defaultMessage: 'Border thickness',
})}
paramName="outlineWeight"
value={stateParams.outlineWeight}
setValue={setValue}
/>
</EuiPanel>

<EuiSpacer size="s" />

<WmsOptions {...props} />
</>
);
}

export { RegionMapOptions };
10 changes: 0 additions & 10 deletions src/legacy/core_plugins/region_map/public/index.scss

This file was deleted.

Loading

0 comments on commit 39ca6bd

Please sign in to comment.