Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Maps] provide drag-n-drop support to order tooltip properties #46631

Merged
merged 25 commits into from
Oct 9, 2019
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
2548fcb
[Maps] tooltip custom labels
nreese Sep 24, 2019
c051daa
Merge branch 'master' of github.com:elastic/kibana into tooltip-sort
nreese Sep 25, 2019
dc6159c
add drag handlers for re-ordering tooltip property order
nreese Sep 25, 2019
13b5ba6
add trash button to remove property
nreese Sep 25, 2019
1ed927c
add jest tests for AddTooltipFieldPopover
nreese Sep 25, 2019
68df57d
sort EMS file tooltip properties
nreese Sep 25, 2019
c41c726
update TooltipSelector jest test
nreese Sep 25, 2019
5490ac0
clean up AddTooltipFieldPopover field sorting
nreese Sep 25, 2019
3e560fb
remove console statements
nreese Sep 25, 2019
b5c165d
add more styles when row is getting dragged
nreese Sep 25, 2019
3ab4f0d
change reorder aria label
nreese Sep 25, 2019
0b4a91b
move css changes into seperate file
nreese Sep 25, 2019
29e71c4
Merge branch 'master' of github.com:elastic/kibana into tooltip-sort
nreese Oct 3, 2019
a627237
allow adding multiple fields before closing popover
nreese Oct 3, 2019
d8344ce
clear checked state on Add
nreese Oct 3, 2019
c24b7ce
update jest snapshots
nreese Oct 3, 2019
39f256c
Merge branch 'master' of github.com:elastic/kibana into tooltip-sort
nreese Oct 7, 2019
21acefb
use FieldIcon to display field type as icon
nreese Oct 7, 2019
1739cfa
add bottom border to tooltip field
nreese Oct 7, 2019
bb758e5
avoid flash after drag and drop
nreese Oct 7, 2019
fc28afe
fix merge conflicts
nreese Oct 9, 2019
f9e22eb
Tooltip styles (#32)
miukimiu Oct 9, 2019
5cec2a9
merge with master and update snapshots
nreese Oct 9, 2019
810b9e3
update TooltipSelector snapshot
nreese Oct 9, 2019
2d7357e
replace 24px with
nreese Oct 9, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions x-pack/legacy/plugins/maps/public/components/_index.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@import './tooltip_selector';

.mapMetricEditorPanel {
margin-bottom: $euiSizeS;
}
Expand All @@ -13,3 +15,5 @@
.mapGeometryFilter__geoFieldItem {
padding: $euiSizeXS;
}


Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
.mapTooltipSelector__propertyRow {
display: flex;

&:hover,
&:focus,
&:focus-within {
.mapTooltipSelector__propertyIcons {
display: block;
animation: mapPropertyIconsBecomeVisible $euiAnimSpeedFast $euiAnimSlightResistance;
}
}

.mapTooltipSelector__propertyIcons {
&:hover,
&:focus {
display: block;
animation: mapPropertyIconsBecomeVisible $euiAnimSpeedFast $euiAnimSlightResistance;
}
}
}

.mapTooltipSelector__propertyRow-isDragging {
@include euiBottomShadowMedium;
}

.mapTooltipSelector__propertyRow-isDraggingOver {
background-color: $euiColorEmptyShade;
// Don't allow interaction events while layer is being re-ordered
pointer-events: none !important;
}

.mapTooltipSelector__propertyContent {
overflow: hidden;
flex-grow: 1;
}

.mapTooltipSelector__propertyIcons {
flex-shrink: 0;
display: none;
}

.mapTooltipSelector__grab:hover {
cursor: grab;
}

@keyframes mapPropertyIconsBecomeVisible {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import React, { Component } from 'react';
import {
EuiPopover,
EuiPopoverTitle,
EuiButtonEmpty,
EuiSelectable,
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';

const sortByLabel = (a, b) => {
if (a.label < b.label) return -1;
if (a.label > b.label) return 1;
return 0;
};

const ENTRY_KEY_INDEX = 0;
const ENTRY_VALUE_INDEX = 1;

export class AddTooltipFieldPopover extends Component {

state = {
isPopoverOpen: false,
};

_togglePopover = () => {
this.setState({
isPopoverOpen: !this.state.isPopoverOpen,
});
}

_closePopover = () => {
this.setState({
isPopoverOpen: false,
});
}

_onSelect = (options) => {
const selectedField = options.find(option => {
return option.checked === 'on';
});
if (selectedField) {
this.props.onSelect(selectedField.value);
}
this._closePopover();
nreese marked this conversation as resolved.
Show resolved Hide resolved
}

_renderAddButton() {
return (
<EuiButtonEmpty
onClick={this._togglePopover}
size="xs"
iconType="plusInCircleFilled"
isDisabled={!this.props.fields}
>
<FormattedMessage
id="xpack.maps.tooltipSelector.addFieldLabel"
defaultMessage="Add tooltip field"
/>
</EuiButtonEmpty>
);
}

_renderContent() {
if (!this.props.fields) {
return null;
}

const fieldsByTypeMap = new Map();

this.props.fields
.filter(field => {
// remove selected fields
const isFieldSelected = !!this.props.selectedFields.find(selectedField => {
return field.name === selectedField.name;
});
return !isFieldSelected;
})
.forEach(field => {
const fieldLabel = 'label' in field ? field.label : field.name;
const option = {
value: field.name,
label: fieldLabel,
};
if (fieldsByTypeMap.has(field.type)) {
const fieldsList = fieldsByTypeMap.get(field.type);
fieldsList.push(option);
fieldsByTypeMap.set(field.type, fieldsList);
} else {
fieldsByTypeMap.set(field.type, [option]);
}
});

const fieldTypeEntries = [...fieldsByTypeMap.entries()];
const options = [];
if (fieldTypeEntries.length === 1) {
// Field list only contains a single type, no need to display group label for type header
options.push(...fieldTypeEntries[0][ENTRY_VALUE_INDEX].sort(sortByLabel));
} else {
// Display group label per type header
fieldTypeEntries
.sort((a, b) => {
if (a[ENTRY_KEY_INDEX] < b[ENTRY_KEY_INDEX]) return -1;
if (a[ENTRY_KEY_INDEX] > b[ENTRY_KEY_INDEX]) return 1;
return 0;
})
.forEach(entry => {
const fieldType = entry[ENTRY_KEY_INDEX];
const fieldTypeOptions = entry[ENTRY_VALUE_INDEX].sort(sortByLabel);
options.push({
label: fieldType,
isGroupLabel: true
});
options.push(...fieldTypeOptions);
});
}

return (
<EuiSelectable
searchable
options={options}
onChange={this._onSelect}
>
{(list, search) => (
<div style={{ width: '300px' }}>
<EuiPopoverTitle>{search}</EuiPopoverTitle>
{list}
</div>
)}
</EuiSelectable>
);
}

render() {
return (
<EuiPopover
id="addTooltipFieldPopover"
anchorPosition="leftCenter"
button={this._renderAddButton()}
isOpen={this.state.isPopoverOpen}
closePopover={this._closePopover}
>
{this._renderContent()}
</EuiPopover>
);
}
}
Loading