diff --git a/package.json b/package.json index d18572ae1dbb..79006b6ea45b 100644 --- a/package.json +++ b/package.json @@ -206,7 +206,6 @@ "raw-loader": "0.5.1", "react": "^16.8.0", "react-addons-shallow-compare": "15.6.2", - "react-anything-sortable": "^1.7.4", "react-color": "^2.13.8", "react-dom": "^16.8.0", "react-grid-layout": "^0.16.2", diff --git a/src/legacy/core_plugins/metrics/public/_tvb_editor.scss b/src/legacy/core_plugins/metrics/public/_tvb_editor.scss new file mode 100644 index 000000000000..9864c72b7662 --- /dev/null +++ b/src/legacy/core_plugins/metrics/public/_tvb_editor.scss @@ -0,0 +1,5 @@ +.tvbEditor { + overflow-y: auto; + overflow-x: hidden; +} + diff --git a/src/legacy/core_plugins/metrics/public/_ui_sortable.scss b/src/legacy/core_plugins/metrics/public/_ui_sortable.scss deleted file mode 100644 index c9f19952cdc7..000000000000 --- a/src/legacy/core_plugins/metrics/public/_ui_sortable.scss +++ /dev/null @@ -1,41 +0,0 @@ -// react-anything-sortable overrides -// Scoped to just the TSVB editor - -.tvbEditor { - - .ui-sortable { - display: block; - position: relative; - overflow: visible; - user-select: none; - - &:before, - &:after { - content: ''; - display: table; - } - - &:after { - clear: both; - } - - .ui-sortable-item.ui-sortable-dragging { - position: absolute; - z-index: $euiZLevel2; - } - - .ui-sortable-placeholder { - display: none; - - &.visible { - display: block; - opacity: .5; - z-index: -1; - } - } - } - -} - - - diff --git a/src/legacy/core_plugins/metrics/public/components/_series_editor.scss b/src/legacy/core_plugins/metrics/public/components/_series_editor.scss index 281abefbf8ce..0cfe5fef010d 100644 --- a/src/legacy/core_plugins/metrics/public/components/_series_editor.scss +++ b/src/legacy/core_plugins/metrics/public/components/_series_editor.scss @@ -9,11 +9,6 @@ .tvbSeriesEditor { margin-bottom: $euiSize; padding: $euiSizeS; - - // When dragging a collapsed item, make sure the contents doesn't show - &.ui-sortable-dragging { - overflow: hidden; - } } .tvbSeries__body { diff --git a/src/legacy/core_plugins/metrics/public/components/aggs/agg.js b/src/legacy/core_plugins/metrics/public/components/aggs/agg.js index aa0cbc535ed1..4702b8903830 100644 --- a/src/legacy/core_plugins/metrics/public/components/aggs/agg.js +++ b/src/legacy/core_plugins/metrics/public/components/aggs/agg.js @@ -20,7 +20,6 @@ import PropTypes from 'prop-types'; import React from 'react'; import aggToComponent from '../lib/agg_to_component'; -import { sortable } from 'react-anything-sortable'; import { UnsupportedAgg } from './unsupported_agg'; import { TemporaryUnsupportedAgg } from './temporary_unsupported_agg'; @@ -46,8 +45,6 @@ function Agg(props) {
); @@ -72,15 +70,11 @@ Agg.propTypes = { onAdd: PropTypes.func, onChange: PropTypes.func, onDelete: PropTypes.func, - onMouseDown: PropTypes.func, - onSortableItemMount: PropTypes.func, - onSortableItemReadyToMove: PropTypes.func, - onTouchStart: PropTypes.func, panel: PropTypes.object, series: PropTypes.object, siblings: PropTypes.array, - sortData: PropTypes.string, uiRestrictions: PropTypes.object, + dragHandleProps: PropTypes.object, }; -export default sortable(Agg); +export default Agg; diff --git a/src/legacy/core_plugins/metrics/public/components/aggs/agg_row.js b/src/legacy/core_plugins/metrics/public/components/aggs/agg_row.js index e778dcb6b446..d218c3f7249e 100644 --- a/src/legacy/core_plugins/metrics/public/components/aggs/agg_row.js +++ b/src/legacy/core_plugins/metrics/public/components/aggs/agg_row.js @@ -19,42 +19,23 @@ import PropTypes from 'prop-types'; import React from 'react'; -import _ from 'lodash'; +import { last } from 'lodash'; import AddDeleteButtons from '../add_delete_buttons'; -import { EuiToolTip, EuiButtonIcon, EuiIcon, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; -import { injectI18n, FormattedMessage } from '@kbn/i18n/react'; +import { EuiIcon, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { injectI18n } from '@kbn/i18n/react'; +import { SeriesDragHandler } from '../series_drag_handler'; function AggRowUi(props) { let iconType = 'eyeClosed'; let iconColor = 'subdued'; - const last = _.last(props.siblings); + const lastSibling = last(props.siblings); const { intl } = props; - if (last.id === props.model.id) { + if (lastSibling.id === props.model.id) { iconType = 'eye'; iconColor = 'text'; } - let dragHandle; - if (!props.disableDelete) { - dragHandle = ( - - )} - > - - - - ); - } - return (
@@ -64,7 +45,9 @@ function AggRowUi(props) { {props.children} - {dragHandle} + + + + {list.map((row, idx) => ( + + {provided => ( + handleAdd(this.props, newMetricAggFn)} + onChange={onChange} + onDelete={() => handleDelete(this.props, row)} + panel={panel} + series={model} + siblings={list} + uiRestrictions={uiRestrictions} + dragHandleProps={provided.dragHandleProps} + /> + )} + + ))} + + ); + } +} + +Aggs.propTypes = { + name: PropTypes.string.isRequired, + fields: PropTypes.object.isRequired, + model: PropTypes.object.isRequired, + onChange: PropTypes.func.isRequired, + panel: PropTypes.object.isRequired, + dragHandleProps: PropTypes.object, +}; diff --git a/src/legacy/core_plugins/metrics/public/components/aggs/calculation.js b/src/legacy/core_plugins/metrics/public/components/aggs/calculation.js index 4f9bdaeeaf31..b086bbd0df1c 100644 --- a/src/legacy/core_plugins/metrics/public/components/aggs/calculation.js +++ b/src/legacy/core_plugins/metrics/public/components/aggs/calculation.js @@ -69,6 +69,7 @@ class CalculationAgg extends Component { onAdd={this.props.onAdd} onDelete={this.props.onDelete} siblings={this.props.siblings} + dragHandleProps={this.props.dragHandleProps} > diff --git a/src/legacy/core_plugins/metrics/public/components/aggs/cumulative_sum.js b/src/legacy/core_plugins/metrics/public/components/aggs/cumulative_sum.js index 09dad215d335..ee320e16794e 100644 --- a/src/legacy/core_plugins/metrics/public/components/aggs/cumulative_sum.js +++ b/src/legacy/core_plugins/metrics/public/components/aggs/cumulative_sum.js @@ -39,6 +39,7 @@ function CumulativeSumAgg(props) { onAdd={props.onAdd} onDelete={props.onDelete} siblings={props.siblings} + dragHandleProps={props.dragHandleProps} > diff --git a/src/legacy/core_plugins/metrics/public/components/aggs/derivative.js b/src/legacy/core_plugins/metrics/public/components/aggs/derivative.js index ee3b7478a117..26c2641ae68c 100644 --- a/src/legacy/core_plugins/metrics/public/components/aggs/derivative.js +++ b/src/legacy/core_plugins/metrics/public/components/aggs/derivative.js @@ -54,6 +54,7 @@ export const DerivativeAgg = props => { onAdd={props.onAdd} onDelete={props.onDelete} siblings={props.siblings} + dragHandleProps={props.dragHandleProps} > diff --git a/src/legacy/core_plugins/metrics/public/components/aggs/filter_ratio.js b/src/legacy/core_plugins/metrics/public/components/aggs/filter_ratio.js index 4b99fde27483..968458cd60c6 100644 --- a/src/legacy/core_plugins/metrics/public/components/aggs/filter_ratio.js +++ b/src/legacy/core_plugins/metrics/public/components/aggs/filter_ratio.js @@ -68,6 +68,7 @@ export const FilterRatioAgg = props => { onAdd={props.onAdd} onDelete={props.onDelete} siblings={props.siblings} + dragHandleProps={props.dragHandleProps} > diff --git a/src/legacy/core_plugins/metrics/public/components/aggs/math.js b/src/legacy/core_plugins/metrics/public/components/aggs/math.js index bc40facc973f..eb4cc8bd3ed5 100644 --- a/src/legacy/core_plugins/metrics/public/components/aggs/math.js +++ b/src/legacy/core_plugins/metrics/public/components/aggs/math.js @@ -69,6 +69,7 @@ class MathAgg extends Component { onAdd={this.props.onAdd} onDelete={this.props.onDelete} siblings={this.props.siblings} + dragHandleProps={this.props.dragHandleProps} > diff --git a/src/legacy/core_plugins/metrics/public/components/aggs/moving_average.js b/src/legacy/core_plugins/metrics/public/components/aggs/moving_average.js index 6c53ddac7115..9a3fc5b147df 100644 --- a/src/legacy/core_plugins/metrics/public/components/aggs/moving_average.js +++ b/src/legacy/core_plugins/metrics/public/components/aggs/moving_average.js @@ -94,6 +94,7 @@ const MovingAverageAggUi = props => { onAdd={props.onAdd} onDelete={props.onDelete} siblings={props.siblings} + dragHandleProps={props.dragHandleProps} > diff --git a/src/legacy/core_plugins/metrics/public/components/aggs/percentile.js b/src/legacy/core_plugins/metrics/public/components/aggs/percentile.js index ee949a624a03..5ca493f8c922 100644 --- a/src/legacy/core_plugins/metrics/public/components/aggs/percentile.js +++ b/src/legacy/core_plugins/metrics/public/components/aggs/percentile.js @@ -232,6 +232,7 @@ class PercentileAgg extends Component { // eslint-disable-line react/no-multi-co onAdd={this.props.onAdd} onDelete={this.props.onDelete} siblings={this.props.siblings} + dragHandleProps={this.props.dragHandleProps} > diff --git a/src/legacy/core_plugins/metrics/public/components/aggs/percentile_rank/percentile_rank.js b/src/legacy/core_plugins/metrics/public/components/aggs/percentile_rank/percentile_rank.js index ccb855d953e1..0092f028e580 100644 --- a/src/legacy/core_plugins/metrics/public/components/aggs/percentile_rank/percentile_rank.js +++ b/src/legacy/core_plugins/metrics/public/components/aggs/percentile_rank/percentile_rank.js @@ -64,6 +64,7 @@ export const PercentileRankAgg = props => { onAdd={props.onAdd} onDelete={props.onDelete} siblings={props.siblings} + dragHandleProps={props.dragHandleProps} > diff --git a/src/legacy/core_plugins/metrics/public/components/aggs/positive_only.js b/src/legacy/core_plugins/metrics/public/components/aggs/positive_only.js index 388bed87e33d..648c1bd97717 100644 --- a/src/legacy/core_plugins/metrics/public/components/aggs/positive_only.js +++ b/src/legacy/core_plugins/metrics/public/components/aggs/positive_only.js @@ -44,6 +44,7 @@ export const PositiveOnlyAgg = props => { onAdd={props.onAdd} onDelete={props.onDelete} siblings={props.siblings} + dragHandleProps={props.dragHandleProps} > diff --git a/src/legacy/core_plugins/metrics/public/components/aggs/serial_diff.js b/src/legacy/core_plugins/metrics/public/components/aggs/serial_diff.js index 01f6bbfdc27d..b5527279d7e2 100644 --- a/src/legacy/core_plugins/metrics/public/components/aggs/serial_diff.js +++ b/src/legacy/core_plugins/metrics/public/components/aggs/serial_diff.js @@ -46,6 +46,7 @@ export const SerialDiffAgg = props => { onAdd={props.onAdd} onDelete={props.onDelete} siblings={props.siblings} + dragHandleProps={props.dragHandleProps} > diff --git a/src/legacy/core_plugins/metrics/public/components/aggs/series_agg.js b/src/legacy/core_plugins/metrics/public/components/aggs/series_agg.js index 3dd14aefcaa4..8316ebbd80f6 100644 --- a/src/legacy/core_plugins/metrics/public/components/aggs/series_agg.js +++ b/src/legacy/core_plugins/metrics/public/components/aggs/series_agg.js @@ -92,6 +92,7 @@ function SeriesAggUi(props) { onAdd={props.onAdd} onDelete={props.onDelete} siblings={props.siblings} + dragHandleProps={props.dragHandleProps} > @@ -112,6 +113,7 @@ function SeriesAggUi(props) { onAdd={props.onAdd} onDelete={props.onDelete} siblings={props.siblings} + dragHandleProps={props.dragHandleProps} > diff --git a/src/legacy/core_plugins/metrics/public/components/aggs/static.js b/src/legacy/core_plugins/metrics/public/components/aggs/static.js index 8d33aed3372d..bde7a90866ce 100644 --- a/src/legacy/core_plugins/metrics/public/components/aggs/static.js +++ b/src/legacy/core_plugins/metrics/public/components/aggs/static.js @@ -56,6 +56,7 @@ export const Static = props => { onAdd={props.onAdd} onDelete={props.onDelete} siblings={props.siblings} + dragHandleProps={props.dragHandleProps} > diff --git a/src/legacy/core_plugins/metrics/public/components/aggs/std_agg.js b/src/legacy/core_plugins/metrics/public/components/aggs/std_agg.js index c081ba473e4d..0442778d4275 100644 --- a/src/legacy/core_plugins/metrics/public/components/aggs/std_agg.js +++ b/src/legacy/core_plugins/metrics/public/components/aggs/std_agg.js @@ -45,6 +45,7 @@ function StandardAgg(props) { onAdd={props.onAdd} onDelete={props.onDelete} siblings={props.siblings} + dragHandleProps={props.dragHandleProps} > diff --git a/src/legacy/core_plugins/metrics/public/components/aggs/std_deviation.js b/src/legacy/core_plugins/metrics/public/components/aggs/std_deviation.js index 5f8c73b00a3f..20dde5a0bd89 100644 --- a/src/legacy/core_plugins/metrics/public/components/aggs/std_deviation.js +++ b/src/legacy/core_plugins/metrics/public/components/aggs/std_deviation.js @@ -83,6 +83,7 @@ const StandardDeviationAggUi = props => { onAdd={props.onAdd} onDelete={props.onDelete} siblings={props.siblings} + dragHandleProps={props.dragHandleProps} > diff --git a/src/legacy/core_plugins/metrics/public/components/aggs/std_sibling.js b/src/legacy/core_plugins/metrics/public/components/aggs/std_sibling.js index 39ec2d9a1840..20fff2e44337 100644 --- a/src/legacy/core_plugins/metrics/public/components/aggs/std_sibling.js +++ b/src/legacy/core_plugins/metrics/public/components/aggs/std_sibling.js @@ -114,6 +114,7 @@ const StandardSiblingAggUi = props => { onAdd={props.onAdd} onDelete={props.onDelete} siblings={props.siblings} + dragHandleProps={props.dragHandleProps} > diff --git a/src/legacy/core_plugins/metrics/public/components/aggs/temporary_unsupported_agg.js b/src/legacy/core_plugins/metrics/public/components/aggs/temporary_unsupported_agg.js index eedc10bdbb03..7032e55a989d 100644 --- a/src/legacy/core_plugins/metrics/public/components/aggs/temporary_unsupported_agg.js +++ b/src/legacy/core_plugins/metrics/public/components/aggs/temporary_unsupported_agg.js @@ -30,6 +30,7 @@ export function TemporaryUnsupportedAgg(props) { onAdd={props.onAdd} onDelete={props.onDelete} siblings={props.siblings} + dragHandleProps={props.dragHandleProps} > diff --git a/src/legacy/core_plugins/metrics/public/components/aggs/top_hit.js b/src/legacy/core_plugins/metrics/public/components/aggs/top_hit.js index 4c475f8cb5f3..bacb8a101373 100644 --- a/src/legacy/core_plugins/metrics/public/components/aggs/top_hit.js +++ b/src/legacy/core_plugins/metrics/public/components/aggs/top_hit.js @@ -147,6 +147,7 @@ const TopHitAggUi = props => { onAdd={props.onAdd} onDelete={props.onDelete} siblings={props.siblings} + dragHandleProps={props.dragHandleProps} > diff --git a/src/legacy/core_plugins/metrics/public/components/aggs/unsupported_agg.js b/src/legacy/core_plugins/metrics/public/components/aggs/unsupported_agg.js index 6637538c5ea6..c45c8a0c16a0 100644 --- a/src/legacy/core_plugins/metrics/public/components/aggs/unsupported_agg.js +++ b/src/legacy/core_plugins/metrics/public/components/aggs/unsupported_agg.js @@ -30,6 +30,7 @@ export function UnsupportedAgg(props) { onAdd={props.onAdd} onDelete={props.onDelete} siblings={props.siblings} + dragHandleProps={props.dragHandleProps} > diff --git a/src/legacy/core_plugins/metrics/public/components/data_format_picker.js b/src/legacy/core_plugins/metrics/public/components/data_format_picker.js index 1b9b407e0753..080afa4fccc7 100644 --- a/src/legacy/core_plugins/metrics/public/components/data_format_picker.js +++ b/src/legacy/core_plugins/metrics/public/components/data_format_picker.js @@ -117,12 +117,9 @@ class DataFormatPicker extends Component { let custom; if (defaultValue === 'duration') { const [from, to, decimals] = value.split(','); - const selectedFrom = durationInputOptions.find(option => { - return from === option.value; - }); - const selectedTo = durationOutputOptions.find(option => { - return to === option.value; - }); + const selectedFrom = durationInputOptions.find(option => from === option.value); + const selectedTo = durationOutputOptions.find(option => to === option.value); + return ( @@ -232,7 +229,6 @@ class DataFormatPicker extends Component { ); } - } DataFormatPicker.defaultProps = { diff --git a/src/legacy/core_plugins/metrics/public/components/lib/create_agg_row_render.js b/src/legacy/core_plugins/metrics/public/components/lib/create_agg_row_render.js deleted file mode 100644 index 91ee48576859..000000000000 --- a/src/legacy/core_plugins/metrics/public/components/lib/create_agg_row_render.js +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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 seriesChangeHandler from './series_change_handler'; -import newMetricAggFn from './new_metric_agg_fn'; -import { handleAdd, handleDelete } from './collection_actions'; -import Agg from '../aggs/agg'; - -export default function createAggRowRender(props) { - return (row, index, items) => { - const { panel, model, fields, uiRestrictions } = props; - const changeHandler = seriesChangeHandler(props, items); - - return ( - - ); - }; -} diff --git a/src/legacy/core_plugins/metrics/public/components/lib/sort_keyhandler.js b/src/legacy/core_plugins/metrics/public/components/lib/reorder.js similarity index 72% rename from src/legacy/core_plugins/metrics/public/components/lib/sort_keyhandler.js rename to src/legacy/core_plugins/metrics/public/components/lib/reorder.js index 936395d12808..89d25cf40be8 100644 --- a/src/legacy/core_plugins/metrics/public/components/lib/sort_keyhandler.js +++ b/src/legacy/core_plugins/metrics/public/components/lib/reorder.js @@ -16,17 +16,14 @@ * specific language governing permissions and limitations * under the License. */ +export const reorder = ( + list, + startIndex, + endIndex, +) => { + const result = Array.from(list); + const [removed] = result.splice(startIndex, 1); + result.splice(endIndex, 0, removed); -import { keyCodes } from '@elastic/eui'; - -export function createUpDownHandler(callback) { - return (ev) => { - if (ev.keyCode === keyCodes.UP) { - ev.preventDefault(); - callback('up'); - } else if (ev.keyCode === keyCodes.DOWN) { - ev.preventDefault(); - callback('down'); - } - }; -} + return result; +}; diff --git a/src/legacy/core_plugins/metrics/public/components/series.js b/src/legacy/core_plugins/metrics/public/components/series.js index eeb1bbee308f..cd4af2ea63e4 100644 --- a/src/legacy/core_plugins/metrics/public/components/series.js +++ b/src/legacy/core_plugins/metrics/public/components/series.js @@ -27,7 +27,6 @@ import topN from './vis_types/top_n/series'; import table from './vis_types/table/series'; import gauge from './vis_types/gauge/series'; import markdown from './vis_types/markdown/series'; -import { sortable } from 'react-anything-sortable'; import { FormattedMessage } from '@kbn/i18n/react'; const lookup = { @@ -76,15 +75,15 @@ class Series extends Component { e.preventDefault(); this.setState({ - visible: !this.state.visible + visible: !this.state.visible, }); }; componentDidMount() { if (this.props.visData$) { this.visDataSubscription = this.props.visData$ - .subscribe(visData => this.setState({ - uiRestrictions: get(visData, 'uiRestrictions') + .subscribe(visData => this.setState({ + uiRestrictions: get(visData, 'uiRestrictions'), })); } } @@ -93,44 +92,35 @@ class Series extends Component { const { panel } = this.props; const Component = lookup[panel.type]; - if (Component) { - const params = { - className: this.props.className, - disableAdd: this.props.disableAdd, - disableDelete: this.props.disableDelete, - fields: this.props.fields, - name: this.props.name, - onAdd: this.props.onAdd, - onChange: this.handleChange, - onClone: this.props.onClone, - onDelete: this.props.onDelete, - onMouseDown: this.props.onMouseDown, - onTouchStart: this.props.onTouchStart, - onShouldSortItem: this.props.onShouldSortItem, - onSortableItemMount: this.props.onSortableItemMount, - onSortableItemReadyToMove: this.props.onSortableItemReadyToMove, - model: this.props.model, - panel: this.props.panel, - selectedTab: this.state.selectedTab, - sortData: this.props.sortData, - style: this.props.style, - uiRestrictions: this.state.uiRestrictions, - switchTab: this.switchTab, - toggleVisible: this.toggleVisible, - togglePanelActivation: this.togglePanelActivation, - visible: this.state.visible, - }; - return (); - } - return ( -
- -
- ); + const params = { + className: this.props.className, + disableAdd: this.props.disableAdd, + disableDelete: this.props.disableDelete, + fields: this.props.fields, + name: this.props.name, + onAdd: this.props.onAdd, + onChange: this.handleChange, + onClone: this.props.onClone, + onDelete: this.props.onDelete, + model: this.props.model, + panel: this.props.panel, + selectedTab: this.state.selectedTab, + style: this.props.style, + uiRestrictions: this.state.uiRestrictions, + switchTab: this.switchTab, + toggleVisible: this.toggleVisible, + togglePanelActivation: this.togglePanelActivation, + visible: this.state.visible, + dragHandleProps: this.props.dragHandleProps, + }; + + return Boolean(Component) ? + () : + (); } componentWillUnmount() { @@ -154,15 +144,10 @@ Series.propTypes = { onChange: PropTypes.func, onClone: PropTypes.func, onDelete: PropTypes.func, - onMouseDown: PropTypes.func, - onShouldSortItem: PropTypes.func.isRequired, - onSortableItemMount: PropTypes.func, - onSortableItemReadyToMove: PropTypes.func, - onTouchStart: PropTypes.func, model: PropTypes.object, panel: PropTypes.object, visData$: PropTypes.object, - sortData: PropTypes.string, + dragHandleProps: PropTypes.object, }; -export default sortable(Series); +export default Series; diff --git a/src/legacy/core_plugins/metrics/public/components/series_drag_handler.js b/src/legacy/core_plugins/metrics/public/components/series_drag_handler.js new file mode 100644 index 000000000000..40ec470fc58a --- /dev/null +++ b/src/legacy/core_plugins/metrics/public/components/series_drag_handler.js @@ -0,0 +1,60 @@ +/* + * 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, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import { EuiFlexItem, EuiToolTip, EuiIcon } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +export class SeriesDragHandler extends PureComponent { + render() { + const { dragHandleProps, hideDragHandler } = this.props; + + return ( + +
+ {!hideDragHandler && ( + + + + )} +
+
+ ); + } +} + +SeriesDragHandler.defaultProps = { + hideDragHandler: true, +}; + +SeriesDragHandler.propTypes = { + hideDragHandler: PropTypes.bool, + dragHandleProps: PropTypes.object.isRequired, +}; diff --git a/src/legacy/core_plugins/metrics/public/components/series_editor.js b/src/legacy/core_plugins/metrics/public/components/series_editor.js index a339108a058b..fd82faca79fa 100644 --- a/src/legacy/core_plugins/metrics/public/components/series_editor.js +++ b/src/legacy/core_plugins/metrics/public/components/series_editor.js @@ -19,95 +19,117 @@ import PropTypes from 'prop-types'; import React, { Component } from 'react'; +import { find } from 'lodash'; import reIdSeries from './lib/re_id_series'; import Series from './series'; import { handleAdd, handleDelete, - handleChange + handleChange, } from './lib/collection_actions'; import newSeriesFn from './lib/new_series_fn'; -import Sortable from 'react-anything-sortable'; +import { EuiDragDropContext, EuiDroppable, EuiDraggable } from '@elastic/eui'; +import { reorder } from './lib/reorder'; + +const DROPPABLE_ID = 'series_editor_dnd'; class SeriesEditor extends Component { - constructor(props) { - super(props); - this.renderRow = this.renderRow.bind(this); - this.sortSeries = this.sortSeries.bind(this); - } - - handleClone(series) { + handleClone = series => { const newSeries = reIdSeries(series); + handleAdd.call(null, this.props, () => newSeries); - } + }; - sortSeries(index, direction, allSeries) { - const newIndex = index + (direction === 'up' ? -1 : 1); - if (newIndex < 0 || newIndex >= allSeries.length) { - // Don't do anything when series is already at the edge - return; + sortHandler = ({ destination, source }) => { + const canSort = destination && source; + + if (canSort) { + const sortFunction = this.getSortFunction({ destination, source }); + + sortFunction({ destination, source }); } + }; - const newSeries = allSeries.slice(0); - const changeWithElement = allSeries[newIndex]; - newSeries[newIndex] = allSeries[index]; - newSeries[index] = changeWithElement; - this.props.onChange({ series: newSeries }); - } - - renderRow(row, index, allSeries) { - const { props } = this; - const { fields, model, name, limit, colorPicker } = props; - return ( - = limit} - disableDelete={model[name].length < 2} - fields={fields} - key={row.id} - onAdd={handleAdd.bind(null, props, newSeriesFn)} - onChange={handleChange.bind(null, props)} - onClone={() => this.handleClone(row)} - onDelete={handleDelete.bind(null, props, row)} - onShouldSortItem={(direction) => this.sortSeries(index, direction, allSeries)} - visData$={this.props.visData$} - model={row} - panel={model} - sortData={row.id} - /> + getSortFunction = ({ destination, source }) => + (destination.droppableId === source.droppableId && source.droppableId === DROPPABLE_ID ? + this.sortSeries : + this.sortAggregations ); - } + + sortSeries = ({ destination, source }) => { + this.props.onChange({ + series: reorder([...this.props.model.series], source.index, destination.index), + }); + }; + + sortAggregations = ({ destination, source }) => { + const extractId = ({ droppableId }) => droppableId.split(':')[1]; + const id = extractId(source); + const canSort = id === extractId(destination); + + if (canSort) { + const model = [...this.props.model.series]; + const series = find(model, { id }); + + series.metrics = reorder([...series.metrics], source.index, destination.index); + + this.props.onChange({ + series: model, + }); + } + }; render() { - const { limit, model, name } = this.props; - const series = model[name] - .filter((val, index) => index < (limit || Infinity)) - .map(this.renderRow); - const handleSort = (data) => { - const series = data.map(id => model[name].find(s => s.id === id)); - this.props.onChange({ series }); - }; + const { limit, model, name, fields, colorPicker } = this.props; + const list = model[name] + .filter((val, index) => index < (limit || Infinity)); + return ( -
- + - { series } - -
+ {list.map((row, idx) => ( + + {provided => ( + = limit} + disableDelete={model[name].length < 2} + fields={fields} + onAdd={() => handleAdd(this.props, newSeriesFn)} + onChange={(doc) => handleChange(this.props, doc)} + onClone={() => this.handleClone(row)} + onDelete={() => handleDelete(this.props, row)} + visData$={this.props.visData$} + model={row} + panel={model} + dragHandleProps={provided.dragHandleProps} + /> + )} + + ))} + + ); } - } + SeriesEditor.defaultProps = { name: 'series', limit: Infinity, - colorPicker: true + colorPicker: true, }; SeriesEditor.propTypes = { diff --git a/src/legacy/core_plugins/metrics/public/components/vis_types/gauge/series.js b/src/legacy/core_plugins/metrics/public/components/vis_types/gauge/series.js index 047543082ce6..802edfd47bc2 100644 --- a/src/legacy/core_plugins/metrics/public/components/vis_types/gauge/series.js +++ b/src/legacy/core_plugins/metrics/public/components/vis_types/gauge/series.js @@ -22,19 +22,19 @@ import React from 'react'; import ColorPicker from '../../color_picker'; import AddDeleteButtons from '../../add_delete_buttons'; import { SeriesConfig } from '../../series_config'; -import Sortable from 'react-anything-sortable'; import Split from '../../split'; -import { EuiToolTip, EuiTabs, EuiTab, EuiFlexGroup, EuiFlexItem, EuiFieldText, EuiButtonIcon } from '@elastic/eui'; -import createAggRowRender from '../../lib/create_agg_row_render'; +import { SeriesDragHandler } from '../../series_drag_handler'; +import { EuiTabs, EuiTab, EuiFlexGroup, EuiFlexItem, EuiFieldText, EuiButtonIcon } from '@elastic/eui'; import createTextHandler from '../../lib/create_text_handler'; -import { createUpDownHandler } from '../../lib/sort_keyhandler'; import { injectI18n, FormattedMessage } from '@kbn/i18n/react'; +import { Aggs } from '../../aggs/aggs'; function GaugeSeriesUi(props) { const { panel, fields, onAdd, + name, onChange, onDelete, disableDelete, @@ -49,7 +49,6 @@ function GaugeSeriesUi(props) { const model = { ...defaults, ...props.model }; const handleChange = createTextHandler(onChange); - const aggs = model.metrics.map(createAggRowRender(props)); let caretIcon = 'arrowDown'; if (!visible) caretIcon = 'arrowRight'; @@ -58,21 +57,17 @@ function GaugeSeriesUi(props) { if (visible) { let seriesBody; if (selectedTab === 'metrics') { - const handleSort = (data) => { - const metrics = data.map(id => model.metrics.find(m => m.id === id)); - props.onChange({ metrics }); - }; seriesBody = (
- - { aggs } - +
); - let dragHandle; - if (!props.disableDelete) { - dragHandle = ( - - )} - > - - - - ); - } - return (
- - { dragHandle } + - { body }
); @@ -217,19 +187,15 @@ GaugeSeriesUi.propTypes = { onChange: PropTypes.func, onClone: PropTypes.func, onDelete: PropTypes.func, - onMouseDown: PropTypes.func, - onSortableItemMount: PropTypes.func, - onSortableItemReadyToMove: PropTypes.func, - onTouchStart: PropTypes.func, model: PropTypes.object, panel: PropTypes.object, selectedTab: PropTypes.string, - sortData: PropTypes.string, style: PropTypes.object, switchTab: PropTypes.func, toggleVisible: PropTypes.func, visible: PropTypes.bool, uiRestrictions: PropTypes.object, + dragHandleProps: PropTypes.object, }; const GaugeSeries = injectI18n(GaugeSeriesUi); diff --git a/src/legacy/core_plugins/metrics/public/components/vis_types/markdown/series.js b/src/legacy/core_plugins/metrics/public/components/vis_types/markdown/series.js index 1f103ac6f0ae..81cde2e75241 100644 --- a/src/legacy/core_plugins/metrics/public/components/vis_types/markdown/series.js +++ b/src/legacy/core_plugins/metrics/public/components/vis_types/markdown/series.js @@ -21,12 +21,12 @@ import PropTypes from 'prop-types'; import React from 'react'; import AddDeleteButtons from '../../add_delete_buttons'; import { SeriesConfig } from '../../series_config'; -import Sortable from 'react-anything-sortable'; import Split from '../../split'; -import createAggRowRender from '../../lib/create_agg_row_render'; import createTextHandler from '../../lib/create_text_handler'; import { EuiTabs, EuiTab, EuiFlexGroup, EuiFlexItem, EuiFieldText, EuiButtonIcon } from '@elastic/eui'; import { injectI18n, FormattedMessage } from '@kbn/i18n/react'; +import { Aggs } from '../../aggs/aggs'; +import { SeriesDragHandler } from '../../series_drag_handler'; function MarkdownSeriesUi(props) { const { @@ -40,6 +40,7 @@ function MarkdownSeriesUi(props) { selectedTab, visible, intl, + name, uiRestrictions } = props; @@ -47,7 +48,6 @@ function MarkdownSeriesUi(props) { const model = { ...defaults, ...props.model }; const handleChange = createTextHandler(onChange); - const aggs = model.metrics.map(createAggRowRender(props)); let caretIcon = 'arrowDown'; if (!visible) caretIcon = 'arrowRight'; @@ -56,21 +56,17 @@ function MarkdownSeriesUi(props) { if (visible) { let seriesBody; if (selectedTab === 'metrics') { - const handleSort = (data) => { - const metrics = data.map(id => model.metrics.find(m => m.id === id)); - props.onChange({ metrics }); - }; seriesBody = (
- - { aggs } - +
@@ -155,6 +149,8 @@ function MarkdownSeriesUi(props) { /> + + - { body }
); - } MarkdownSeriesUi.propTypes = { @@ -187,19 +181,15 @@ MarkdownSeriesUi.propTypes = { onChange: PropTypes.func, onClone: PropTypes.func, onDelete: PropTypes.func, - onMouseDown: PropTypes.func, - onSortableItemMount: PropTypes.func, - onSortableItemReadyToMove: PropTypes.func, - onTouchStart: PropTypes.func, model: PropTypes.object, panel: PropTypes.object, selectedTab: PropTypes.string, - sortData: PropTypes.string, style: PropTypes.object, switchTab: PropTypes.func, toggleVisible: PropTypes.func, visible: PropTypes.bool, uiRestrictions: PropTypes.object, + dragHandleProps: PropTypes.object, }; const MarkdownSeries = injectI18n(MarkdownSeriesUi); diff --git a/src/legacy/core_plugins/metrics/public/components/vis_types/metric/series.js b/src/legacy/core_plugins/metrics/public/components/vis_types/metric/series.js index 0df8136a81c3..e05ff8cf6a54 100644 --- a/src/legacy/core_plugins/metrics/public/components/vis_types/metric/series.js +++ b/src/legacy/core_plugins/metrics/public/components/vis_types/metric/series.js @@ -22,18 +22,18 @@ import React from 'react'; import ColorPicker from '../../color_picker'; import AddDeleteButtons from '../../add_delete_buttons'; import { SeriesConfig } from '../../series_config'; -import Sortable from 'react-anything-sortable'; import Split from '../../split'; -import { EuiToolTip, EuiTabs, EuiTab, EuiFlexGroup, EuiFlexItem, EuiFieldText, EuiButtonIcon } from '@elastic/eui'; -import createAggRowRender from '../../lib/create_agg_row_render'; +import { SeriesDragHandler } from '../../series_drag_handler'; +import { EuiTabs, EuiTab, EuiFlexGroup, EuiFlexItem, EuiFieldText, EuiButtonIcon } from '@elastic/eui'; import createTextHandler from '../../lib/create_text_handler'; -import { createUpDownHandler } from '../../lib/sort_keyhandler'; import { injectI18n, FormattedMessage } from '@kbn/i18n/react'; +import { Aggs } from '../../aggs/aggs'; function MetricSeriesUi(props) { const { panel, fields, + name, onAdd, onChange, onDelete, @@ -49,7 +49,6 @@ function MetricSeriesUi(props) { const model = { ...defaults, ...props.model }; const handleChange = createTextHandler(onChange); - const aggs = model.metrics.map(createAggRowRender(props)); let caretIcon = 'arrowDown'; if (!visible) caretIcon = 'arrowRight'; @@ -58,21 +57,17 @@ function MetricSeriesUi(props) { if (visible) { let seriesBody; if (selectedTab === 'metrics') { - const handleSort = (data) => { - const metrics = data.map(id => model.metrics.find(m => m.id === id)); - props.onChange({ metrics }); - }; seriesBody = (
- - { aggs } - +
- )} - > - - - - ); - } - return (
@@ -185,7 +157,7 @@ function MetricSeriesUi(props) { /> - { dragHandle } + - { body }
); @@ -221,20 +192,16 @@ MetricSeriesUi.propTypes = { onChange: PropTypes.func, onClone: PropTypes.func, onDelete: PropTypes.func, - onMouseDown: PropTypes.func, - onSortableItemMount: PropTypes.func, - onSortableItemReadyToMove: PropTypes.func, - onTouchStart: PropTypes.func, model: PropTypes.object, panel: PropTypes.object, selectedTab: PropTypes.string, - sortData: PropTypes.string, style: PropTypes.object, switchTab: PropTypes.func, toggleVisible: PropTypes.func, visible: PropTypes.bool, togglePanelActivation: PropTypes.func, uiRestrictions: PropTypes.object, + dragHandleProps: PropTypes.object, }; const MetricSeries = injectI18n(MetricSeriesUi); diff --git a/src/legacy/core_plugins/metrics/public/components/vis_types/table/is_sortable.js b/src/legacy/core_plugins/metrics/public/components/vis_types/table/is_sortable.js index 3f7e20a8df35..e308d3ce93af 100644 --- a/src/legacy/core_plugins/metrics/public/components/vis_types/table/is_sortable.js +++ b/src/legacy/core_plugins/metrics/public/components/vis_types/table/is_sortable.js @@ -18,6 +18,7 @@ */ import basicAggs from '../../../../common/basic_aggs'; + export function isSortable(metric) { return basicAggs.includes(metric.type); } diff --git a/src/legacy/core_plugins/metrics/public/components/vis_types/table/series.js b/src/legacy/core_plugins/metrics/public/components/vis_types/table/series.js index d253be8608eb..e3f7d438d122 100644 --- a/src/legacy/core_plugins/metrics/public/components/vis_types/table/series.js +++ b/src/legacy/core_plugins/metrics/public/components/vis_types/table/series.js @@ -21,28 +21,30 @@ import React from 'react'; import PropTypes from 'prop-types'; import AddDeleteButtons from '../../add_delete_buttons'; import SeriesConfig from './config'; -import Sortable from 'react-anything-sortable'; -import { EuiToolTip, EuiTabs, EuiTab, EuiFlexGroup, EuiFlexItem, EuiFieldText, EuiButtonIcon } from '@elastic/eui'; +import { SeriesDragHandler } from '../../series_drag_handler'; +import { EuiTabs, EuiTab, EuiFlexGroup, EuiFlexItem, EuiFieldText, EuiButtonIcon } from '@elastic/eui'; import createTextHandler from '../../lib/create_text_handler'; -import createAggRowRender from '../../lib/create_agg_row_render'; -import { createUpDownHandler } from '../../lib/sort_keyhandler'; import { FormattedMessage, injectI18n } from '@kbn/i18n/react'; +import { Aggs } from '../../aggs/aggs'; function TableSeries(props) { const { model, onAdd, + name, + fields, + panel, onChange, onDelete, disableDelete, disableAdd, selectedTab, visible, - intl + intl, + uiRestrictions, } = props; const handleChange = createTextHandler(onChange); - const aggs = model.metrics.map(createAggRowRender(props)); let caretIcon = 'arrowDown'; if (!visible) caretIcon = 'arrowRight'; @@ -51,21 +53,17 @@ function TableSeries(props) { if (visible) { let seriesBody; if (selectedTab === 'metrics') { - const handleSort = (data) => { - const metrics = data.map(id => model.metrics.find(m => m.id === id)); - props.onChange({ metrics }); - }; seriesBody = (
- - { aggs } - +
); } else { @@ -106,33 +104,10 @@ function TableSeries(props) { ); } - let dragHandle; - if (!props.disableDelete) { - dragHandle = ( - - )} - > - - - - ); - } - return (
@@ -155,7 +130,7 @@ function TableSeries(props) { /> - { dragHandle } + { - const metrics = data.map(id => model.metrics.find(m => m.id === id)); - props.onChange({ metrics }); - }; seriesBody = (
- - { aggs } - +
); - let dragHandle; - if (!props.disableDelete) { - dragHandle = ( - - )} - > - - - - ); - } - return (
@@ -188,7 +158,7 @@ const TimeseriesSeries = injectI18n(function (props) { /> - { dragHandle } + - { body }
); @@ -224,21 +193,16 @@ TimeseriesSeries.propTypes = { onChange: PropTypes.func, onClone: PropTypes.func, onDelete: PropTypes.func, - onMouseDown: PropTypes.func, - onShouldSortItem: PropTypes.func.isRequired, - onSortableItemMount: PropTypes.func, - onSortableItemReadyToMove: PropTypes.func, - onTouchStart: PropTypes.func, model: PropTypes.object, panel: PropTypes.object, selectedTab: PropTypes.string, - sortData: PropTypes.string, style: PropTypes.object, switchTab: PropTypes.func, toggleVisible: PropTypes.func, visible: PropTypes.bool, togglePanelActivation: PropTypes.func, uiRestrictions: PropTypes.object, + dragHandleProps: PropTypes.object, }; export default injectI18n(TimeseriesSeries); diff --git a/src/legacy/core_plugins/metrics/public/components/vis_types/top_n/series.js b/src/legacy/core_plugins/metrics/public/components/vis_types/top_n/series.js index 8d095a024b0d..c73f54284d2e 100644 --- a/src/legacy/core_plugins/metrics/public/components/vis_types/top_n/series.js +++ b/src/legacy/core_plugins/metrics/public/components/vis_types/top_n/series.js @@ -22,18 +22,18 @@ import React from 'react'; import ColorPicker from '../../color_picker'; import AddDeleteButtons from '../../add_delete_buttons'; import { SeriesConfig } from '../../series_config'; -import Sortable from 'react-anything-sortable'; import Split from '../../split'; -import { EuiToolTip, EuiTabs, EuiTab, EuiFlexGroup, EuiFlexItem, EuiFieldText, EuiButtonIcon } from '@elastic/eui'; +import { SeriesDragHandler } from '../../series_drag_handler'; +import { EuiTabs, EuiTab, EuiFlexGroup, EuiFlexItem, EuiFieldText, EuiButtonIcon } from '@elastic/eui'; import createTextHandler from '../../lib/create_text_handler'; -import createAggRowRender from '../../lib/create_agg_row_render'; -import { createUpDownHandler } from '../../lib/sort_keyhandler'; import { FormattedMessage, injectI18n } from '@kbn/i18n/react'; +import { Aggs } from '../../aggs/aggs'; const TopNSeries = injectI18n(function (props) { const { panel, model, + name, fields, onAdd, onChange, @@ -47,7 +47,6 @@ const TopNSeries = injectI18n(function (props) { } = props; const handleChange = createTextHandler(onChange); - const aggs = model.metrics.map(createAggRowRender(props)); let caretIcon = 'arrowDown'; if (!visible) caretIcon = 'arrowRight'; @@ -56,21 +55,17 @@ const TopNSeries = injectI18n(function (props) { if (visible) { let seriesBody; if (selectedTab === 'metrics') { - const handleSort = data => { - const metrics = data.map(id => model.metrics.find(m => m.id === id)); - props.onChange({ metrics }); - }; seriesBody = (
- - { aggs } - +
); - let dragHandle; - if (!props.disableDelete) { - dragHandle = ( - - )} - > - - - - ); - } - return (
@@ -180,7 +152,7 @@ const TopNSeries = injectI18n(function (props) { /> - { dragHandle } +