Skip to content

Commit

Permalink
Add rectangle ui tool bar
Browse files Browse the repository at this point in the history
Signed-off-by: Vijayan Balasubramanian <[email protected]>
  • Loading branch information
VijayanB committed Mar 15, 2023
1 parent b01eb6d commit e1823aa
Show file tree
Hide file tree
Showing 8 changed files with 259 additions and 1 deletion.
3 changes: 3 additions & 0 deletions common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ export enum TOOLTIP_STATE {
export enum FILTER_DRAW_MODE {
NONE = 'none', // draw filter is inactive
POLYGON = 'polygon', // Filter is active and set to draw polygon
RECTANGLE = 'rectangle', // Filter is active and set to draw rectangle
}

export interface DrawFilterProperties {
Expand All @@ -164,5 +165,7 @@ export interface DrawFilterProperties {

export const DRAW_FILTER_SHAPE_TITLE = 'DRAW SHAPE';
export const DRAW_FILTER_POLYGON_DEFAULT_LABEL = 'polygon';
export const DRAW_FILTER_RECTANGLE_DEFAULT_LABEL = 'rectangle';
export const DRAW_FILTER_POLYGON = 'Draw Polygon';
export const DRAW_FILTER_RECTANGLE = 'Draw Rectangle';
export const DRAW_FILTER_SPATIAL_RELATIONS = ['intersects', 'disjoint', 'within'];
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`renders filter by rectangle button 1`] = `
<EuiPopover
anchorPosition="leftUp"
button={
<EuiPanel
className="spatialFilterToolbar__shape"
paddingSize="none"
>
<EuiButtonIcon
aria-label="draw_filter_rectangle"
color="text"
iconType={Object {}}
isDisabled={false}
onClick={[Function]}
size="s"
title="Draw Rectangle"
/>
</EuiPanel>
}
closePopover={[Function]}
data-test-subj="drawRectanglePopOver"
display="inlineBlock"
hasArrow={true}
id="drawRectangleId"
isOpen={false}
ownFocus={true}
panelPaddingSize="none"
>
<EuiContextMenu
initialPanelId={0}
panels={
Array [
Object {
"content": <FilterInputPanel
defaultFilterLabel="rectangle"
drawLabel="Draw Rectangle"
mode="rectangle"
onSubmit={[Function]}
relations={
Array [
"intersects",
"disjoint",
"within",
]
}
/>,
"id": 0,
"title": "DRAW SHAPE",
},
]
}
size="m"
/>
</EuiPopover>
`;

exports[`renders filter by rectangle in middle of drawing 1`] = `
<EuiPopover
anchorPosition="leftUp"
button={
<EuiPanel
className="spatialFilterToolbar__shape"
paddingSize="none"
>
<EuiButtonIcon
aria-label="draw_filter_rectangle"
color="text"
iconType={Object {}}
isDisabled={true}
onClick={[Function]}
size="s"
title="Draw Rectangle"
/>
</EuiPanel>
}
closePopover={[Function]}
data-test-subj="drawRectanglePopOver"
display="inlineBlock"
hasArrow={true}
id="drawRectangleId"
isOpen={false}
ownFocus={true}
panelPaddingSize="none"
>
<EuiContextMenu
initialPanelId={0}
panels={
Array [
Object {
"content": <FilterInputPanel
defaultFilterLabel="rectangle"
drawLabel="Draw Rectangle"
mode="rectangle"
onSubmit={[Function]}
relations={
Array [
"intersects",
"disjoint",
"within",
]
}
/>,
"id": 0,
"title": "DRAW SHAPE",
},
]
}
size="m"
/>
</EuiPopover>
`;
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ exports[`renders spatial filter before drawing 1`] = `
isDrawActive={false}
setDrawFilterProperties={[MockFunction]}
/>
<FilterByRectangle
isDrawActive={false}
setDrawFilterProperties={[MockFunction]}
/>
</EuiFlexItem>
</EuiFlexGroup>
`;
Expand All @@ -36,6 +40,10 @@ exports[`renders spatial filter while drawing 1`] = `
isDrawActive={true}
setDrawFilterProperties={[MockFunction]}
/>
<FilterByRectangle
isDrawActive={true}
setDrawFilterProperties={[MockFunction]}
/>
</EuiFlexItem>
</EuiFlexGroup>
`;
14 changes: 13 additions & 1 deletion public/components/toolbar/spatial_filter/draw_filter_shape.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,19 @@ import React, { Fragment, useEffect, useRef } from 'react';
import { IControl, Map as Maplibre } from 'maplibre-gl';
import MapboxDraw from '@mapbox/mapbox-gl-draw';
import { Feature } from 'geojson';
import { DrawFilterProperties, FILTER_DRAW_MODE} from '../../../../common';
import { DrawRectangle } from '../../draw/modes/rectangle';
import { DrawFilterProperties, FILTER_DRAW_MODE } from '../../../../common';

interface DrawFilterShapeProps {
filterProperties: DrawFilterProperties;
map: Maplibre;
updateFilterProperties: (properties: DrawFilterProperties) => void;
}

const additionalDrawMode = {
DRAW_RECTANGLE: 'draw_rectangle',
};

export const DrawFilterShape = ({
filterProperties,
map,
Expand All @@ -27,6 +33,10 @@ export const DrawFilterShape = ({
const mapboxDrawRef = useRef<MapboxDraw>(
new MapboxDraw({
displayControlsDefault: false,
modes: {
...MapboxDraw.modes,
[additionalDrawMode.DRAW_RECTANGLE]: DrawRectangle,
},
})
);

Expand All @@ -47,6 +57,8 @@ export const DrawFilterShape = ({
useEffect(() => {
if (filterProperties.mode === FILTER_DRAW_MODE.POLYGON) {
mapboxDrawRef.current.changeMode('draw_polygon');
} else if (filterProperties.mode === FILTER_DRAW_MODE.RECTANGLE) {
mapboxDrawRef.current.changeMode('draw_rectangle');
} else {
// default mode
mapboxDrawRef.current.changeMode('simple_select');
Expand Down
4 changes: 4 additions & 0 deletions public/components/toolbar/spatial_filter/draw_tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ const getTooltipContent = (mode: FILTER_DRAW_MODE): string => {
return i18n.translate('maps.drawFilterPolygon.tooltipContent', {
defaultMessage: 'Click to start shape. Click for vertex. Double click to finish.',
});
case FILTER_DRAW_MODE.RECTANGLE:
return i18n.translate('maps.drawFilterRectangle.tooltipContent', {
defaultMessage: 'Click and drag to draw rectangle.',
});
default:
return i18n.translate('maps.drawFilterDefault.tooltipContent', {
defaultMessage: 'Click to start shape. Double click to finish.',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/
import { shallow } from 'enzyme';
import React from 'react';
import { FilterByRectangle } from './filter_by_rectangle';

it('renders filter by rectangle button', () => {
const mockCallback = jest.fn();
const component = shallow(
<FilterByRectangle setDrawFilterProperties={mockCallback} isDrawActive={false} />
);
expect(component).toMatchSnapshot();
});

it('renders filter by rectangle in middle of drawing', () => {
const mockCallback = jest.fn();
const component = shallow(
<FilterByRectangle setDrawFilterProperties={mockCallback} isDrawActive={true} />
);
expect(component).toMatchSnapshot();
});
90 changes: 90 additions & 0 deletions public/components/toolbar/spatial_filter/filter_by_rectangle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import React, { useState } from 'react';
import { EuiPopover, EuiContextMenu, EuiPanel, EuiButtonIcon } from '@elastic/eui';
import { FilterInputPanel } from './filter_input_panel';
// TODO: replace with rectangle image file once available
import rectangle from '../../../images/polygon.svg';
import {
DrawFilterProperties,
DRAW_FILTER_SPATIAL_RELATIONS,
DRAW_FILTER_SHAPE_TITLE,
DRAW_FILTER_RECTANGLE,
DRAW_FILTER_RECTANGLE_DEFAULT_LABEL,
} from '../../../../common';
import { FILTER_DRAW_MODE } from '../../../../common';

interface FilterByRectangleProps {
setDrawFilterProperties: (properties: DrawFilterProperties) => void;
isDrawActive: boolean;
}

export const FilterByRectangle = ({
setDrawFilterProperties,
isDrawActive,
}: FilterByRectangleProps) => {
const [isPopoverOpen, setPopover] = useState(false);

const onClick = () => {
setPopover(!isPopoverOpen);
};

const closePopover = () => {
setPopover(false);
};

const onSubmit = (input: { relation: string; label: string; mode: FILTER_DRAW_MODE }) => {
setDrawFilterProperties({
mode: input.mode,
relation: input.relation,
filterLabel: input.label,
});
closePopover();
};

const panels = [
{
id: 0,
title: DRAW_FILTER_SHAPE_TITLE,
content: (
<FilterInputPanel
drawLabel={DRAW_FILTER_RECTANGLE}
defaultFilterLabel={DRAW_FILTER_RECTANGLE_DEFAULT_LABEL}
relations={DRAW_FILTER_SPATIAL_RELATIONS}
onSubmit={onSubmit}
mode={FILTER_DRAW_MODE.RECTANGLE}
/>
),
},
];

const drawRectangleButton = (
<EuiPanel paddingSize="none" className="spatialFilterToolbar__shape">
<EuiButtonIcon
color="text"
size={'s'}
iconType={rectangle}
onClick={onClick}
aria-label={'draw_filter_rectangle'}
title={DRAW_FILTER_RECTANGLE}
isDisabled={isDrawActive}
/>
</EuiPanel>
);
return (
<EuiPopover
id="drawRectangleId"
button={drawRectangleButton}
isOpen={isPopoverOpen}
closePopover={closePopover}
panelPaddingSize="none"
anchorPosition="leftUp"
data-test-subj="drawRectanglePopOver"
>
<EuiContextMenu initialPanelId={0} panels={panels} />
</EuiPopover>
);
};
5 changes: 5 additions & 0 deletions public/components/toolbar/spatial_filter/filter_toolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import React from 'react';
import { EuiButton, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import { FilterByPolygon } from './filter_by_polygon';
import { FILTER_DRAW_MODE, DrawFilterProperties } from '../../../../common';
import {FilterByRectangle} from "./filter_by_rectangle";

interface SpatialFilterToolBarProps {
setFilterProperties: (properties: DrawFilterProperties) => void;
Expand All @@ -25,6 +26,10 @@ export const SpatialFilterToolbar = ({
const filterIconGroups = (
<EuiFlexItem>
<FilterByPolygon setDrawFilterProperties={setFilterProperties} isDrawActive={isDrawActive} />
<FilterByRectangle
setDrawFilterProperties={setFilterProperties}
isDrawActive={isDrawActive}
/>
</EuiFlexItem>
);
if (isDrawActive) {
Expand Down

0 comments on commit e1823aa

Please sign in to comment.