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

[TSVB] add controls to toggle disable/enable individual series and annotations #33107

Merged
merged 3 commits into from
Mar 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import PropTypes from 'prop-types';
import React from 'react';
import { EuiToolTip, EuiButtonIcon, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { isBoolean } from 'lodash';

function AddDeleteButtons(props) {
const { testSubj } = props;
Expand Down Expand Up @@ -59,43 +60,85 @@ function AddDeleteButtons(props) {
</EuiFlexItem>
);
};

const createClone = () => {
let cloneBtn = null;

if (props.onClone && !props.disableAdd) {
cloneBtn = (
<EuiFlexItem grow={false}>
<EuiToolTip content={props.cloneTooltip}>
<EuiButtonIcon
data-test-subj={`${testSubj}CloneBtn`}
aria-label={props.cloneTooltip}
iconType="copy"
onClick={props.onClone}
/>
</EuiToolTip>
</EuiFlexItem>
);
}

return cloneBtn;
};

const createActivatePanel = () => {
let activatePanelBtn = null;

if (isBoolean(props.isPanelActive)) {
const tooltip = props.isPanelActive ? props.deactivatePanelTooltip : props.activatePanelTooltip;
const iconType = props.isPanelActive ? 'eye' : 'eyeClosed';

activatePanelBtn = (
<EuiFlexItem grow={false}>
<EuiToolTip content={tooltip} >
<EuiButtonIcon
data-test-subj={`${testSubj}ActivatePanelBtn`}
aria-label={tooltip}
iconType={iconType}
onClick={props.togglePanelActivation}
/>
</EuiToolTip>
</EuiFlexItem>
);
}

return activatePanelBtn;
};

const deleteBtn = createDelete();
const addBtn = createAdd();
let clone;
if (props.onClone && !props.disableAdd) {
clone = (
<EuiFlexItem grow={false}>
<EuiToolTip content={props.cloneTooltip}>
<EuiButtonIcon
data-test-subj={`${testSubj}CloneBtn`}
aria-label={props.cloneTooltip}
iconType="copy"
onClick={props.onClone}
/>
</EuiToolTip>
</EuiFlexItem>
);
}
const cloneBtn = createClone();
const activatePanelBtn = createActivatePanel();

return (
<EuiFlexGroup gutterSize="s" responsive={props.responsive} justifyContent="flexEnd">
{ clone }
{ addBtn }
{ deleteBtn }
{activatePanelBtn}
{cloneBtn}
{addBtn}
{deleteBtn}
</EuiFlexGroup>
);
}

AddDeleteButtons.defaultProps = {
testSubj: 'Add',
activeTooltip: i18n.translate('tsvb.addDeleteButtons.addButtonDefaultTooltip', { defaultMessage: 'Add' }),
addTooltip: i18n.translate('tsvb.addDeleteButtons.addButtonDefaultTooltip', { defaultMessage: 'Add' }),
deleteTooltip: i18n.translate('tsvb.addDeleteButtons.deleteButtonDefaultTooltip', { defaultMessage: 'Delete' }),
cloneTooltip: i18n.translate('tsvb.addDeleteButtons.cloneButtonDefaultTooltip', { defaultMessage: 'Clone' })
cloneTooltip: i18n.translate('tsvb.addDeleteButtons.cloneButtonDefaultTooltip', { defaultMessage: 'Clone' }),
activatePanelTooltip: i18n.translate('tsvb.addDeleteButtons.reEnableTooltip', { defaultMessage: 'Re-enable' }),
deactivatePanelTooltip: i18n.translate('tsvb.addDeleteButtons.temporarilyDisableTooltip', { defaultMessage: 'Temporarily Disable' }),
};

AddDeleteButtons.propTypes = {
addTooltip: PropTypes.string,
deleteTooltip: PropTypes.string,
cloneTooltip: PropTypes.string,
activatePanelTooltip: PropTypes.string,
deactivatePanelTooltip: PropTypes.string,
togglePanelActivation: PropTypes.func,
isPanelActive: PropTypes.bool,
disableAdd: PropTypes.bool,
disableDelete: PropTypes.bool,
onClone: PropTypes.func,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ class AnnotationsEditor extends Component {
const fn = collectionActions.handleChange.bind(null, this.props);
fn(_.assign({}, model, part));
};
const togglePanelActivation = () => {
handleChange({
hidden: !model.hidden,
});
};
const htmlId = htmlIdGenerator(model.id);
const handleAdd = collectionActions.handleAdd
.bind(null, this.props, newAnnotation);
Expand Down Expand Up @@ -249,6 +254,8 @@ class AnnotationsEditor extends Component {
<AddDeleteButtons
onAdd={handleAdd}
onDelete={handleDelete}
togglePanelActivation={togglePanelActivation}
isPanelActive={!model.hidden}
/>
</EuiFlexItem>
</EuiFlexGroup>
Expand Down
34 changes: 20 additions & 14 deletions src/legacy/core_plugins/metrics/public/components/series.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,38 +36,43 @@ const lookup = {
metric,
timeseries,
gauge,
markdown
markdown,
};

class Series extends Component {

constructor(props) {
super(props);

this.state = {
visible: true,
selectedTab: 'metrics'
selectedTab: 'metrics',
};
this.handleChange = this.handleChange.bind(this);
this.switchTab = this.switchTab.bind(this);
this.toggleVisible = this.toggleVisible.bind(this);
}

switchTab(selectedTab) {
switchTab = (selectedTab) => {
this.setState({ selectedTab });
}
};

handleChange(part) {
handleChange = (part) => {
if (this.props.onChange) {
const { model } = this.props;
const doc = _.assign({}, model, part);
this.props.onChange(doc);
}
}
};

toggleVisible(e) {
togglePanelActivation = () => {
const { model } = this.props;

this.handleChange({
hidden: !model.hidden,
});
};

toggleVisible = (e) => {
e.preventDefault();
this.setState({ visible: !this.state.visible });
}
};

render() {
const { panel } = this.props;
Expand Down Expand Up @@ -95,7 +100,8 @@ class Series extends Component {
style: this.props.style,
switchTab: this.switchTab,
toggleVisible: this.toggleVisible,
visible: this.state.visible
togglePanelActivation: this.togglePanelActivation,
visible: this.state.visible,
};
return (<Component {...params}/>);
}
Expand All @@ -113,7 +119,7 @@ class Series extends Component {
}

Series.defaultProps = {
name: 'metrics'
name: 'metrics',
};

Series.propTypes = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ GaugeSeriesUi.propTypes = {
style: PropTypes.object,
switchTab: PropTypes.func,
toggleVisible: PropTypes.func,
visible: PropTypes.bool
visible: PropTypes.bool,
};

const GaugeSeries = injectI18n(GaugeSeriesUi);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ function getColors(props) {
function GaugeVisualization(props) {
const { backgroundColor, model, visData } = props;
const colors = getColors(props);

const series = _.get(visData, `${model.id}.series`, [])
.filter(row => row)
.map((row, i) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ MarkdownSeriesUi.propTypes = {
style: PropTypes.object,
switchTab: PropTypes.func,
toggleVisible: PropTypes.func,
visible: PropTypes.bool
visible: PropTypes.bool,
};

const MarkdownSeries = injectI18n(MarkdownSeriesUi);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,8 @@ function MetricSeriesUi(props) {
onDelete={onDelete}
onClone={props.onClone}
onAdd={onAdd}
togglePanelActivation={props.togglePanelActivation}
isPanelActive={!model.hidden}
disableDelete={disableDelete}
disableAdd={disableAdd}
responsive={false}
Expand Down Expand Up @@ -228,7 +230,8 @@ MetricSeriesUi.propTypes = {
style: PropTypes.object,
switchTab: PropTypes.func,
toggleVisible: PropTypes.func,
visible: PropTypes.bool
visible: PropTypes.bool,
togglePanelActivation: PropTypes.func,
};

const MetricSeries = injectI18n(MetricSeriesUi);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ function TableSeries(props) {
onDelete={onDelete}
onClone={props.onClone}
onAdd={onAdd}
togglePanelActivation={props.togglePanelActivation}
isPanelActive={!model.hidden}
disableDelete={disableDelete}
disableAdd={disableAdd}
responsive={false}
Expand Down Expand Up @@ -198,7 +200,8 @@ TableSeries.propTypes = {
style: PropTypes.object,
switchTab: PropTypes.func,
toggleVisible: PropTypes.func,
visible: PropTypes.bool
visible: PropTypes.bool,
togglePanelActivation: PropTypes.func,
};

export default injectI18n(TableSeries);
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ class TableVis extends Component {
this.dateFormatter = new DateFormat({}, this.props.getConfig);
}

get visibleSeries() {
return _
.get(this.props, 'model.series', [])
.filter(series => !series.hidden);
}

renderRow = row => {
const { model } = this.props;
let rowDisplay = model.pivot_type === 'date' ? this.dateFormatter.convert(row.key) : row.key;
Expand All @@ -65,7 +71,7 @@ class TableVis extends Component {
rowDisplay = (<a href={url}>{rowDisplay}</a>);
}
const columns = row.series.filter(item => item).map(item => {
const column = model.series.find(c => c.id === item.id);
const column = this.visibleSeries.find(c => c.id === item.id);
if (!column) return null;
const formatter = tickFormatter(column.formatter, column.value_template, this.props.getConfig);
const value = formatter(item.last);
Expand All @@ -74,14 +80,14 @@ class TableVis extends Component {
const trendIcon = item.slope > 0 ? 'sortUp' : 'sortDown';
trend = (
<span>
&nbsp; <EuiIcon type={trendIcon} color="subdued" />
&nbsp; <EuiIcon type={trendIcon} color="subdued"/>
</span>
);
}
const style = { color: getColor(column.color_rules, 'text', item.last) };
return (
<td key={`${row.key}-${item.id}`} data-test-subj="tvbTableVis__value" className="eui-textRight" style={style}>
<span>{ value }</span>
<span>{value}</span>
{trend}
</td>
);
Expand All @@ -92,16 +98,17 @@ class TableVis extends Component {
{columns}
</tr>
);
}
};

renderHeader() {
const { model, uiState, onUiState } = this.props;
const stateKey = `${model.type}.sort`;
const sort = uiState.get(stateKey, {
column: '_default_',
order: 'asc'
order: 'asc',
});
const columns = model.series.map(item => {

const columns = this.visibleSeries.map(item => {
const metric = _.last(item.metrics);
const label = metric.type === 'percentile' ?
getPercentileLabel(metric, item) :
Expand All @@ -125,7 +132,7 @@ class TableVis extends Component {
sortIcon = 'empty';
}
sortComponent = (
<EuiIcon type={sortIcon} />
<EuiIcon type={sortIcon}/>
);
}
let headerContent = (
Expand Down Expand Up @@ -162,7 +169,7 @@ class TableVis extends Component {
sortIcon = 'empty';
}
const sortComponent = (
<EuiIcon type={sortIcon} />
<EuiIcon type={sortIcon}/>
);
const handleSortClick = () => {
let order;
Expand All @@ -176,7 +183,7 @@ class TableVis extends Component {
return (
<tr>
<th className="eui-textLeft" scope="col" onClick={handleSortClick}>{label} {sortComponent}</th>
{ columns }
{columns}
</tr>
);
}
Expand All @@ -201,14 +208,14 @@ class TableVis extends Component {
rows = (
<tr>
<td
colSpan={model.series.length + 1}
colSpan={this.visibleSeries.length + 1}
>
{message}
</td>
</tr>
);
}
return(
return (
<div className="tvbVis" data-test-subj="tableView">
<table className="table">
<thead>
Expand All @@ -225,7 +232,7 @@ class TableVis extends Component {
}

TableVis.defaultProps = {
sort: {}
sort: {},
};

TableVis.propTypes = {
Expand All @@ -236,7 +243,7 @@ TableVis.propTypes = {
onUiState: PropTypes.func,
uiState: PropTypes.object,
pageNumber: PropTypes.number,
getConfig: PropTypes.func
getConfig: PropTypes.func,
};

export default TableVis;
Loading