diff --git a/x-pack/plugins/maps/public/_animations.scss b/x-pack/plugins/maps/public/_animations.scss new file mode 100644 index 0000000000000..fde47a7da36e1 --- /dev/null +++ b/x-pack/plugins/maps/public/_animations.scss @@ -0,0 +1,39 @@ +@keyframes mapAnimationHeadShake { + 0% { + transform: translateX(0); + } + + 6.5% { + transform: translateX(-6px) rotateY(-9deg); + } + + 18.5% { + transform: translateX(5px) rotateY(7deg); + } + + 31.5% { + transform: translateX(-3px) rotateY(-5deg); + } + + 43.5% { + transform: translateX(2px) rotateY(3deg); + } + + 50% { + transform: translateX(0); + } +} + +@keyframes mapAnimationPulse { + from { + transform: scale3d(1, 1, 1); + } + + 50% { + transform: scale3d(1.005, 1.005, 1.005); + } + + to { + transform: scale3d(1, 1, 1); + } +} \ No newline at end of file diff --git a/x-pack/plugins/maps/public/_index.scss b/x-pack/plugins/maps/public/_index.scss index 5332464ade9fb..01363209cfffd 100644 --- a/x-pack/plugins/maps/public/_index.scss +++ b/x-pack/plugins/maps/public/_index.scss @@ -13,3 +13,4 @@ @import 'connected_components/index'; @import 'components/index'; @import 'classes/index'; +@import 'animations'; \ No newline at end of file diff --git a/x-pack/plugins/maps/public/actions/layer_actions.ts b/x-pack/plugins/maps/public/actions/layer_actions.ts index 1d239a75d1499..0072fcceb0d2e 100644 --- a/x-pack/plugins/maps/public/actions/layer_actions.ts +++ b/x-pack/plugins/maps/public/actions/layer_actions.ts @@ -256,9 +256,10 @@ export function setSelectedLayer(layerId: string | null) { } if (layerId) { dispatch(trackCurrentLayerState(layerId)); - } - if (getDrawMode(getState()) !== DRAW_MODE.NONE) { - dispatch(setDrawMode(DRAW_MODE.NONE)); + // Reset draw mode only if setting a new selected layer + if (getDrawMode(getState()) !== DRAW_MODE.NONE) { + dispatch(setDrawMode(DRAW_MODE.NONE)); + } } dispatch({ type: SET_SELECTED_LAYER, diff --git a/x-pack/plugins/maps/public/actions/map_actions.ts b/x-pack/plugins/maps/public/actions/map_actions.ts index 464e4dbc6d5ae..a1c7e2f7b453c 100644 --- a/x-pack/plugins/maps/public/actions/map_actions.ts +++ b/x-pack/plugins/maps/public/actions/map_actions.ts @@ -27,6 +27,7 @@ import { getSearchSessionMapBuffer, getLayerById, getEditState, + getSelectedLayerId, } from '../selectors/map_selectors'; import { CLEAR_GOTO, @@ -342,6 +343,19 @@ export function updateEditShape(shapeToDraw: DRAW_SHAPE | null) { }; } +export function setEditLayerToSelectedLayer() { + return async ( + dispatch: ThunkDispatch, + getState: () => MapStoreState + ) => { + const layerId = getSelectedLayerId(getState()); + if (!layerId) { + return; + } + dispatch(updateEditLayer(layerId)); + }; +} + export function updateEditLayer(layerId: string | null) { return (dispatch: Dispatch) => { if (layerId !== null) { diff --git a/x-pack/plugins/maps/public/classes/layers/layer_wizard_registry.ts b/x-pack/plugins/maps/public/classes/layers/layer_wizard_registry.ts index b14ba7cf693b0..4f43d0384940c 100644 --- a/x-pack/plugins/maps/public/classes/layers/layer_wizard_registry.ts +++ b/x-pack/plugins/maps/public/classes/layers/layer_wizard_registry.ts @@ -38,6 +38,7 @@ export type LayerWizard = { prerequisiteSteps?: Array<{ id: string; label: string }>; renderWizard(renderWizardArguments: RenderWizardArguments): ReactElement; title: string; + showFeatureEditTools?: boolean; }; export type LayerWizardWithMeta = LayerWizard & { diff --git a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/config.tsx b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/config.tsx index c4464c8787c19..5df11407b83bd 100644 --- a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/config.tsx +++ b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/config.tsx @@ -45,6 +45,7 @@ export const newVectorLayerWizardConfig: LayerWizard = { renderWizard: (renderWizardArguments: RenderWizardArguments) => { return ; }, + showFeatureEditTools: true, title: i18n.translate('xpack.maps.newVectorLayerWizard.title', { defaultMessage: 'Create new layer', }), diff --git a/x-pack/plugins/maps/public/components/tooltip_selector/__snapshots__/add_tooltip_field_popover.test.tsx.snap b/x-pack/plugins/maps/public/components/tooltip_selector/__snapshots__/add_tooltip_field_popover.test.tsx.snap index 84534515dfa57..875f5df72b1be 100644 --- a/x-pack/plugins/maps/public/components/tooltip_selector/__snapshots__/add_tooltip_field_popover.test.tsx.snap +++ b/x-pack/plugins/maps/public/components/tooltip_selector/__snapshots__/add_tooltip_field_popover.test.tsx.snap @@ -54,7 +54,9 @@ exports[`Should remove selected fields from selectable 1`] = ` - + @@ -143,7 +145,9 @@ exports[`Should render 1`] = ` - + diff --git a/x-pack/plugins/maps/public/components/tooltip_selector/add_tooltip_field_popover.tsx b/x-pack/plugins/maps/public/components/tooltip_selector/add_tooltip_field_popover.tsx index 04ae7af62fddc..3804e3873b47e 100644 --- a/x-pack/plugins/maps/public/components/tooltip_selector/add_tooltip_field_popover.tsx +++ b/x-pack/plugins/maps/public/components/tooltip_selector/add_tooltip_field_popover.tsx @@ -164,14 +164,14 @@ export class AddTooltipFieldPopover extends Component { > {(list, search) => (
- {search} + {search} {list}
)} - + { + dispatch(setEditLayerToSelectedLayer()); + dispatch(setDrawMode(DRAW_MODE.DRAW_SHAPES)); + }, }; } diff --git a/x-pack/plugins/maps/public/connected_components/add_layer_panel/view.tsx b/x-pack/plugins/maps/public/connected_components/add_layer_panel/view.tsx index 2b18d87f03c89..4b3b10889790a 100644 --- a/x-pack/plugins/maps/public/connected_components/add_layer_panel/view.tsx +++ b/x-pack/plugins/maps/public/connected_components/add_layer_panel/view.tsx @@ -33,6 +33,7 @@ export interface Props { hasPreviewLayers: boolean; isLoadingPreviewLayers: boolean; promotePreviewLayers: () => void; + enableEditMode: () => void; } interface State { @@ -91,6 +92,9 @@ export class AddLayerPanel extends Component { if (this.state.layerSteps.length - 1 === this.state.currentStepIndex) { // last step this.props.promotePreviewLayers(); + if (this.state.layerWizard?.showFeatureEditTools) { + this.props.enableEditMode(); + } } else { this.setState((prevState) => { const nextIndex = prevState.currentStepIndex + 1; diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/_toc_entry.scss b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/_toc_entry.scss index d49ce3f0b7530..094d116b78623 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/_toc_entry.scss +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/_toc_entry.scss @@ -32,6 +32,23 @@ .mapTocEntry-isInEditingMode { background-color: tintOrShade($euiColorPrimary, 90%, 70%) !important; + font-size: $euiFontSizeXS; + font-weight: $euiFontWeightMedium; + + &__row { + margin-left: $euiSizeL; + display: inline-flex; + align-items: center; + + > * { + margin-right: $euiSizeXS; + } + } + + &__editFeatureText { + line-height: 1; + padding-right: $euiSizeXS; + } } .mapTocEntry-isDragging { diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/index.ts b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/index.ts index e9c386ce5f8bd..7f879e8501629 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/index.ts +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/index.ts @@ -29,7 +29,10 @@ import { hideTOCDetails, showTOCDetails, toggleLayerVisible, + setDrawMode, + updateDrawState, } from '../../../../../actions'; +import { DRAW_MODE } from '../../../../../../common'; function mapStateToProps(state: MapStoreState, ownProps: OwnProps): ReduxStateProps { const flyoutDisplay = getFlyoutDisplay(state); @@ -63,6 +66,10 @@ function mapDispatchToProps(dispatch: ThunkDispatch { dispatch(toggleLayerVisible(layerId)); }, + cancelEditing: () => { + dispatch(updateDrawState(null)); + dispatch(setDrawMode(DRAW_MODE.NONE)); + }, }; } diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.test.tsx b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.test.tsx index e6439f80411d1..21688b4631f00 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.test.tsx +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.test.tsx @@ -63,6 +63,7 @@ const defaultProps = { hideTOCDetails: () => {}, showTOCDetails: () => {}, editModeActiveForLayer: false, + cancelEditing: () => {}, }; describe('TOCEntry', () => { diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.tsx b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.tsx index 329e7751f67c5..2a933aab6c098 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.tsx +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.tsx @@ -8,8 +8,8 @@ import React, { Component } from 'react'; import classNames from 'classnames'; import type { DraggableProvidedDragHandleProps } from 'react-beautiful-dnd'; - -import { EuiIcon, EuiButtonIcon, EuiConfirmModal } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { EuiIcon, EuiButtonIcon, EuiConfirmModal, EuiButtonEmpty } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { TOCEntryActionsPopover } from './toc_entry_actions_popover'; import { @@ -40,6 +40,7 @@ export interface ReduxDispatchProps { hideTOCDetails: (layerId: string) => void; showTOCDetails: (layerId: string) => void; toggleVisible: (layerId: string) => void; + cancelEditing: () => void; } export interface OwnProps { @@ -332,6 +333,24 @@ export class TOCEntry extends Component { {this._renderDetailsToggle()} {this._renderCancelModal()} + + {this.props.editModeActiveForLayer && ( +
+ + + + + + + +
+ )} ); } diff --git a/x-pack/plugins/maps/public/connected_components/timeslider/_index.scss b/x-pack/plugins/maps/public/connected_components/timeslider/_index.scss index 6e16961575095..cf000967eb23e 100644 --- a/x-pack/plugins/maps/public/connected_components/timeslider/_index.scss +++ b/x-pack/plugins/maps/public/connected_components/timeslider/_index.scss @@ -1,53 +1,17 @@ +$timesliderWidth: 585px; + .mapTimeslider { @include euiBottomShadowLarge; position: fixed; left: 50%; bottom: $euiSize; - transform: translateX(-50%); - min-width: 530px; + // we could center with translateX but this would impact the animation + margin-left: -($timesliderWidth / 2); + width: $timesliderWidth; z-index: 99999; background: $euiColorEmptyShade; - padding: $euiSizeL $euiSizeXL; + padding: $euiSizeL $euiSize; border-radius: $euiSize; - - .euiRangeTick { - overflow-x: hidden; - text-overflow: ellipsis; - font-size: $euiFontSizeXS; - position: relative; - padding-top: $euiSize; - color: $euiColorDarkShade; - - &::before { - @include size($euiSizeXS); - width: 3px; - height: $euiSizeS; - content: ''; - background-color: $euiColorLightShade; - position: absolute; - top: $euiSizeXS; - left: calc(50% - #{($euiSizeXS/2)}); - } - - &--isCustom { - position: absolute; - transform: translateX(-50%); - } - - &:enabled:hover, - &:focus, - &--selected { - color: $euiColorPrimary; - } - - &--selected { - font-weight: $euiFontWeightMedium; - } - - &:disabled { - cursor: not-allowed; - } - } } .mapTimeslider__row { @@ -60,6 +24,10 @@ > * { align-items: center; } + + &:first-child { + padding: 0 $euiSize; + } } .mapTimeslider__close { @@ -77,6 +45,10 @@ .mapTimeslider__controls { margin-left: $euiSizeS; + + .euiButtonIcon + .euiButtonIcon { + margin-left: $euiSizeXS; + } } .mapTimeslider__innerPanel { @@ -87,3 +59,11 @@ display: inline-flex; align-items: center; } + +.mapTimeslider__playButton { + border-radius: 50%; +} + +.mapTimeslider--animation { + animation: mapAnimationPulse .6s ease-in-out; +} diff --git a/x-pack/plugins/maps/public/connected_components/timeslider/timeslider.tsx b/x-pack/plugins/maps/public/connected_components/timeslider/timeslider.tsx index fb3d87b3aa432..08d3af09b60a1 100644 --- a/x-pack/plugins/maps/public/connected_components/timeslider/timeslider.tsx +++ b/x-pack/plugins/maps/public/connected_components/timeslider/timeslider.tsx @@ -166,7 +166,7 @@ class KeyedTimeslider extends Component { render() { return ( -
+
{
- { }) } /> +
@@ -228,6 +230,7 @@ class KeyedTimeslider extends Component { max={this.state.max} step={1} ticks={this.state.ticks} + isDraggable />
diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/_toolbar_overlay.scss b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/_toolbar_overlay.scss index 459a22c82401c..511de91e964b9 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/_toolbar_overlay.scss +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/_toolbar_overlay.scss @@ -52,6 +52,10 @@ } } +.mapToolbarOverlay__buttonGroupAnimated { + animation: mapAnimationHeadShake 1.2s ease-in-out; +} + .mapToolbarOverlay__button__exit { .euiButtonIcon { color: $euiColorDangerText !important; diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/feature_edit_tools.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/feature_edit_tools.tsx index a2b3b20ae1877..ce900cb1e9d65 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/feature_edit_tools.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/feature_edit_tools.tsx @@ -19,7 +19,6 @@ export interface ReduxStateProps { export interface ReduxDispatchProps { setDrawShape: (shapeToDraw: DRAW_SHAPE) => void; - cancelEditing: () => void; } export interface OwnProps { @@ -37,7 +36,10 @@ export function FeatureEditTools(props: Props) { const deleteSelected = props.drawShape === DRAW_SHAPE.DELETE; return ( - + {props.pointsOnly ? null : ( <> - - ); } diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/index.ts index 2e103eb2c8c09..727bbbb8c84a3 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/index.ts +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/index.ts @@ -14,9 +14,9 @@ import { ReduxStateProps, OwnProps, } from './feature_edit_tools'; -import { setDrawMode, updateEditShape } from '../../../../actions'; +import { updateEditShape } from '../../../../actions'; import { MapStoreState } from '../../../../reducers/store'; -import { DRAW_MODE, DRAW_SHAPE } from '../../../../../common'; +import { DRAW_SHAPE } from '../../../../../common'; import { getEditState } from '../../../../selectors/map_selectors'; function mapStateToProps(state: MapStoreState): ReduxStateProps { @@ -33,9 +33,6 @@ function mapDispatchToProps( setDrawShape: (shapeToDraw: DRAW_SHAPE) => { dispatch(updateEditShape(shapeToDraw)); }, - cancelEditing: () => { - dispatch(setDrawMode(DRAW_MODE.NONE)); - }, }; } diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/timeslider_toggle_button/clock_play_icon.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/timeslider_toggle_button/clock_play_icon.tsx deleted file mode 100644 index bc24889d2ec2c..0000000000000 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/timeslider_toggle_button/clock_play_icon.tsx +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { FunctionComponent } from 'react'; - -interface Props { - title?: string; - titleId?: string; -} - -export const ClockPlayIcon: FunctionComponent = ({ title, titleId, ...props }) => ( - - {title ? {title} : null} - - - - -); diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/timeslider_toggle_button/timeslider_toggle_button.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/timeslider_toggle_button/timeslider_toggle_button.tsx index 9332c2baaa502..5811d1e970a35 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/timeslider_toggle_button/timeslider_toggle_button.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/timeslider_toggle_button/timeslider_toggle_button.tsx @@ -8,7 +8,6 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { EuiButtonIcon, EuiPanel } from '@elastic/eui'; -import { ClockPlayIcon } from './clock_play_icon'; export interface Props { isTimesliderOpen: boolean; @@ -39,10 +38,11 @@ export function TimesliderToggleButton(props: Props) { size="s" onClick={onClick} data-test-subj="timesliderToggleButton" - iconType={ClockPlayIcon} - color={props.isTimesliderOpen ? 'primary' : 'text'} + iconType="timeslider" aria-label={label} title={label} + isSelected={props.isTimesliderOpen} + display={props.isTimesliderOpen ? 'fill' : 'empty'} /> );