This commit is contained in:
Erik Sundell
2018-12-19 14:19:27 +01:00
parent 9e558b70d7
commit a955caa9ac
9 changed files with 162 additions and 468 deletions
@@ -4,7 +4,8 @@ import { QueryEditor } from './components/QueryEditor';
export function registerAngularDirectives() {
react2AngularDirective('queryEditor', QueryEditor, [
'target',
'onChange',
'onQueryChange',
'onExecuteQuery',
['uiSegmentSrv', { watchDepth: 'reference' }],
['datasource', { watchDepth: 'reference' }],
['templateSrv', { watchDepth: 'reference' }],
@@ -39,7 +39,7 @@ export class AggregationPicker extends React.Component<Props, State> {
}
componentDidMount() {
this.setAggOptions();
this.setAggOptions(this.props);
}
componentWillReceiveProps(nextProps: Props) {
@@ -49,17 +49,21 @@ export class AggregationPicker extends React.Component<Props, State> {
nextProps.metricKind !== metricKind ||
nextProps.aggregation.groupBys !== aggregation.groupBys
) {
this.setAggOptions();
this.setAggOptions(nextProps);
}
}
setAggOptions() {
const { valueType, metricKind, aggregation, templateSrv } = this.props;
setAggOptions({ valueType, metricKind, aggregation }) {
const { templateSrv } = this.props;
let aggregations = getAggregationOptionsByMetric(valueType, metricKind).map(a => ({
...a,
label: a.text,
}));
if (!aggregations.find(o => o.value === templateSrv.replace(aggregation.crossSeriesReducer))) {
if (
aggregations.length > 0 &&
!aggregations.find(o => o.value === templateSrv.replace(aggregation.crossSeriesReducer))
) {
this.deselectAggregationOption('REDUCE_NONE');
}
@@ -67,15 +71,7 @@ export class AggregationPicker extends React.Component<Props, State> {
aggregations = aggregations.filter(o => o.value !== 'REDUCE_NONE');
this.deselectAggregationOption('REDUCE_NONE');
}
this.setState({
aggOptions: [
this.getTemplateVariablesGroup(),
{
label: 'Aggregations',
options: aggregations,
},
],
});
this.setState({ aggOptions: aggregations });
}
deselectAggregationOption(notValidOptionValue: string) {
@@ -86,17 +82,6 @@ export class AggregationPicker extends React.Component<Props, State> {
handleAggregationChange(value) {
this.props.onChange(value);
// this.$scope.refresh();
}
getTemplateVariablesGroup() {
return {
label: 'Template Variables',
options: this.props.templateSrv.variables.map(v => ({
label: `$${v.name}`,
value: `$${v.name}`,
})),
};
}
render() {
@@ -108,16 +93,15 @@ export class AggregationPicker extends React.Component<Props, State> {
<div className="gf-form-inline">
<div className="gf-form">
<label className="gf-form-label query-keyword width-9">Aggregation</label>
<div className="gf-form-select-wrapper gf-form-select-wrapper--caret-indent">
<StackdriverPicker
onChange={value => this.handleAggregationChange(value)}
selected={aggregation.crossSeriesReducer}
options={aggOptions}
searchable={true}
placeholder="Select Aggregation"
className="width-15"
/>
</div>
<StackdriverPicker
onChange={value => this.handleAggregationChange(value)}
selected={aggregation.crossSeriesReducer}
options={aggOptions}
searchable={true}
placeholder="Select Aggregation"
className="width-15"
groupName="Aggregations"
/>
</div>
<div className="gf-form gf-form--grow">
<label className="gf-form-label gf-form-label--grow">
@@ -1,12 +1,13 @@
import React from 'react';
import _ from 'lodash';
import Segment from './Segment';
import { QueryMeta, Target } from '../types';
import { FilterSegments } from '../filter_segments';
import { getAngularLoader, AngularComponent } from 'app/core/services/AngularLoader';
import '../query_filter_ctrl';
export interface Props {
onChange: (metricDescriptor) => void;
filtersChanged: (filters) => void;
groupBysChanged: (groupBys) => void;
templateSrv: any;
labelData: QueryMeta;
loading: Promise<any>;
@@ -14,226 +15,44 @@ export interface Props {
uiSegmentSrv: any;
}
interface State {
defaultRemoveGroupByValue: string;
resourceTypeValue: string;
groupBySegments: any[];
// filterSegments: FilterSegments;
filterSegments: any;
removeSegment?: any;
}
export class Filter extends React.Component<Props, any> {
element: any;
component: AngularComponent;
export class Filter extends React.Component<Props, State> {
state: State = {
defaultRemoveGroupByValue: '-- remove group by --',
resourceTypeValue: 'resource.type',
groupBySegments: [],
filterSegments: new FilterSegments(this.getFilterKeys.bind(this), this.getFilterValues.bind(this)),
};
constructor(props) {
super(props);
}
componentDidMount() {
this.initSegments(false);
}
shouldComponentUpdate(nextProps) {
return this.state.filterSegments.filterSegments.length > 0;
}
initSegments(hideGroupBys: boolean) {
this.state.filterSegments.init(this.props.uiSegmentSrv);
if (!hideGroupBys) {
this.setState({
groupBySegments: this.props.target.aggregation.groupBys.map(groupBy => {
return this.props.uiSegmentSrv.getSegmentForValue(groupBy);
}),
});
this.ensurePlusButton(this.state.groupBySegments);
async componentDidMount() {
if (!this.element) {
return;
}
this.setState({
removeSegment: this.props.uiSegmentSrv.newSegment({ fake: true, value: '-- remove group by --' }),
});
const { loading, labelData, target, filtersChanged, groupBysChanged } = this.props;
const loader = getAngularLoader();
const template = '<stackdriver-filter> </stackdriver-filter>';
this.state.filterSegments.buildSegmentModel(this.props.target.filters);
}
async createLabelKeyElements() {
await this.props.loading;
let elements = Object.keys(this.props.labelData.metricLabels || {}).map(l => {
return this.props.uiSegmentSrv.newSegment({
value: `metric.label.${l}`,
expandable: false,
});
});
elements = [
...elements,
...Object.keys(this.props.labelData.resourceLabels || {}).map(l => {
return this.props.uiSegmentSrv.newSegment({
value: `resource.label.${l}`,
expandable: false,
});
}),
];
if (this.props.labelData.resourceTypes && this.props.labelData.resourceTypes.length > 0) {
elements = [
...elements,
this.props.uiSegmentSrv.newSegment({
value: this.state.resourceTypeValue,
expandable: false,
}),
];
}
return elements;
}
async getFilterKeys(segment, removeText?: string) {
let elements = await this.createLabelKeyElements();
if (this.props.target.filters.indexOf(this.state.resourceTypeValue) !== -1) {
elements = elements.filter(e => e.value !== this.state.resourceTypeValue);
}
const noValueOrPlusButton = !segment || segment.type === 'plus-button';
if (noValueOrPlusButton && elements.length === 0) {
return [];
}
return [
...elements,
this.props.uiSegmentSrv.newSegment({ fake: true, value: removeText || this.state.defaultRemoveGroupByValue }),
];
}
async getGroupBys(segment) {
let elements = await this.createLabelKeyElements();
elements = elements.filter(e => this.props.target.aggregation.groupBys.indexOf(e.value) === -1);
const noValueOrPlusButton = !segment || segment.type === 'plus-button';
if (noValueOrPlusButton && elements.length === 0) {
return [];
}
this.state.removeSegment.value = this.state.defaultRemoveGroupByValue;
return [...elements, this.state.removeSegment];
}
groupByChanged(segment, index) {
if (segment.value === this.state.removeSegment.value) {
// this.groupBySegments.splice(index, 1);
} else {
segment.type = 'value';
}
const reducer = (memo, seg) => {
if (!seg.fake) {
memo.push(seg.value);
}
return memo;
const scopeProps = {
loading,
labelData,
target,
filtersChanged,
groupBysChanged,
};
this.props.target.aggregation.groupBys = this.state.groupBySegments.reduce(reducer, []);
this.ensurePlusButton(this.state.groupBySegments);
// this.$rootScope.$broadcast('metricTypeChanged');
// this.$scope.refresh();
this.component = loader.load(this.element, scopeProps, template);
}
async getFilters(segment, index) {
await this.props.loading;
const hasNoFilterKeys =
this.props.labelData.metricLabels && Object.keys(this.props.labelData.metricLabels).length === 0;
return this.state.filterSegments.getFilters(segment, index, hasNoFilterKeys);
componentDidUpdate() {
const scope = this.component.getScope();
scope.loading = _.clone(this.props.loading);
scope.labelData = _.cloneDeep(this.props.labelData);
scope.target = _.cloneDeep(this.props.target);
}
getFilterValues(index) {
const filterKey = this.props.templateSrv.replace(this.state.filterSegments.filterSegments[index - 2].value);
if (
!filterKey ||
!this.props.labelData.metricLabels ||
Object.keys(this.props.labelData.metricLabels).length === 0
) {
return [];
}
const shortKey = filterKey.substring(filterKey.indexOf('.label.') + 7);
if (filterKey.startsWith('metric.label.') && this.props.labelData.metricLabels.hasOwnProperty(shortKey)) {
return this.props.labelData.metricLabels[shortKey];
}
if (filterKey.startsWith('resource.label.') && this.props.labelData.resourceLabels.hasOwnProperty(shortKey)) {
return this.props.labelData.resourceLabels[shortKey];
}
if (filterKey === this.state.resourceTypeValue) {
return this.props.labelData.resourceTypes;
}
return [];
}
filterSegmentUpdated(segment, index) {
this.props.target.filters = this.state.filterSegments.filterSegmentUpdated(segment, index);
// this.$scope.refresh();
}
ensurePlusButton(segments) {
const count = segments.length;
const lastSegment = segments[Math.max(count - 1, 0)];
if (!lastSegment || lastSegment.type !== 'plus-button') {
segments.push(this.props.uiSegmentSrv.newPlusButton());
componentWillUnmount() {
if (this.component) {
this.component.destroy();
}
}
render() {
const { filterSegments } = this.state;
// const { metrifilterSegmentscType } = this.props;
return (
<React.Fragment>
<div className="gf-form-inline">
<div className="gf-form">
<span className="gf-form-label query-keyword width-9">Filter</span>
<div className="gf-form">
{filterSegments.filterSegments.map((segment, i) => (
<Segment
key={i}
segment={segment}
getOptions={() => this.getFilters(segment, i)}
onChange={segment => this.filterSegmentUpdated(segment, i)}
/>
))}
</div>
</div>
<div className="gf-form gf-form--grow">
<div className="gf-form-label gf-form-label--grow" />
</div>
</div>
{/* <div className="gf-form-inline" ng-hide="ctrl.$scope.hideGroupBys">
<div className="gf-form">
<span className="gf-form-label query-keyword width-9">Group By</span>
<div className="gf-form" ng-repeat="segment in ctrl.groupBySegments">
<Segment
segment="segment"
get-options="ctrl.getGroupBys(segment)"
on-change="ctrl.groupByChanged(segment, $index)"
/>
</div>
</div>
<div className="gf-form gf-form--grow">
<div className="gf-form-label gf-form-label--grow" />
</div>
</div> */}
</React.Fragment>
);
return <div ref={element => (this.element = element)} style={{ width: '100%' }} />;
}
}
@@ -4,11 +4,12 @@ import appEvents from 'app/core/app_events';
import { MetricPicker } from './MetricPicker';
import { Filter } from './Filter';
// import { AggregationPicker } from './AggregationPicker';
import { AggregationPicker } from './AggregationPicker';
import { Target, QueryMeta } from '../types';
export interface Props {
onChange: (target: Target) => void;
onQueryChange: (target: Target) => void;
onExecuteQuery?: () => void;
target: Target;
datasource: any;
templateSrv: any;
@@ -24,6 +25,8 @@ interface State {
const DefaultTarget: Target = {
defaultProject: 'loading project...',
metricType: '',
metricKind: '',
valueType: '',
refId: '',
service: '',
unit: '',
@@ -35,22 +38,14 @@ const DefaultTarget: Target = {
},
filters: [],
aliasBy: '',
metricKind: '',
valueType: '',
};
export class QueryEditor extends React.Component<Props, State> {
state: State = { labelData: null, loadLabelsPromise: null, target: DefaultTarget };
constructor(props) {
super(props);
this.handleMetricTypeChange = this.handleMetricTypeChange.bind(this);
this.handleAggregationChange = this.handleAggregationChange.bind(this);
}
state: State = { labelData: null, loadLabelsPromise: new Promise(() => {}), target: DefaultTarget };
componentDidMount() {
this.setState({ target: this.props.target });
this.getLabels();
this.setState({ target: this.props.target });
}
async getLabels() {
@@ -81,18 +76,50 @@ export class QueryEditor extends React.Component<Props, State> {
});
// this.$rootScope.$broadcast('metricTypeChanged');
// this.getLabels();
// this.refresh();
this.getLabels();
this.props.onQueryChange(this.state.target);
this.props.onExecuteQuery();
}
handleAggregationChange(crossSeriesReducer) {
// this.target.aggregation.crossSeriesReducer = crossSeriesReducer;
// this.refresh();
handleFilterChange(value) {
this.setState({
target: {
...this.state.target,
filters: value,
},
});
this.props.onQueryChange(this.state.target);
this.props.onExecuteQuery();
}
handleGroupBysChange(value) {
this.setState({
target: {
...this.state.target,
groupBys: value,
},
});
this.props.onQueryChange(this.state.target);
this.props.onExecuteQuery();
}
handleAggregationChange(value) {
this.setState({
target: {
...this.state.target,
aggregation: {
...this.state.target.aggregation,
crossSeriesReducer: value,
},
},
});
this.props.onQueryChange(this.state.target);
this.props.onExecuteQuery();
}
render() {
const { labelData, loadLabelsPromise, target } = this.state;
const { defaultProject, metricType } = target;
const { defaultProject, metricType, valueType, metricKind, aggregation } = target;
const { templateSrv, datasource, uiSegmentSrv } = this.props;
return (
@@ -105,13 +132,21 @@ export class QueryEditor extends React.Component<Props, State> {
onChange={value => this.handleMetricTypeChange(value)}
/>
<Filter
onChange={() => console.log('change filter')}
filtersChanged={value => this.handleFilterChange(value)}
groupBysChanged={value => this.handleGroupBysChange(value)}
target={target}
uiSegmentSrv={uiSegmentSrv}
labelData={labelData}
templateSrv={templateSrv}
loading={loadLabelsPromise}
/>
<AggregationPicker
valueType={valueType}
metricKind={metricKind}
templateSrv={templateSrv}
aggregation={aggregation}
onChange={value => this.handleAggregationChange(value)}
/>
{/* target="ctrl.target" refresh="ctrl.refresh()" loading="ctrl.loadLabelsPromise" label-data="ctrl.labelData" */}
{/* <stackdriver-filter
target="target"
@@ -4,21 +4,14 @@ export const DefaultFilterValue = 'select value';
export class FilterSegments {
filterSegments: any[];
removeSegment: any;
uiSegmentSrv: any;
constructor(private getFilterKeysFunc, private getFilterValuesFunc) {
this.filterSegments = [];
}
constructor(private uiSegmentSrv, private target, private getFilterKeysFunc, private getFilterValuesFunc) {}
init(uiSegmentSrv) {
this.uiSegmentSrv = uiSegmentSrv;
}
buildSegmentModel(filters) {
buildSegmentModel() {
this.removeSegment = this.uiSegmentSrv.newSegment({ fake: true, value: DefaultRemoveFilterValue });
this.filterSegments = [];
filters.forEach((f, index) => {
this.target.filters.forEach((f, index) => {
switch (index % 4) {
case 0:
this.filterSegments.push(this.uiSegmentSrv.newKey(f));
@@ -1,5 +1,5 @@
<query-editor-row query-ctrl="ctrl" has-text-edit-mode="false">
<query-editor target="ctrl.target" template-srv="ctrl.templateSrv" datasource="ctrl.datasource" on-change="ctrl.handleTargetChange" ui-segment-srv=ctrl.uiSegmentSrv></query-editor>
<query-editor target="ctrl.target" template-srv="ctrl.templateSrv" datasource="ctrl.datasource" on-query-change="ctrl.handleQueryChange" on-execute-query="ctrl.handleExecuteQuery" ui-segment-srv=ctrl.uiSegmentSrv></query-editor>
<!-- <metric-picker target="ctrl.target" default-project="ctrl.target.defaultProject" metric-type="ctrl.target.metricType" template-srv="ctrl.templateSrv" datasource="ctrl.datasource" on-change="ctrl.handleMetricTypeChange"></metric-picker>
<stackdriver-filter target="ctrl.target" refresh="ctrl.refresh()" loading="ctrl.loadLabelsPromise" label-data="ctrl.labelData"
></stackdriver-filter>
@@ -1,31 +1,33 @@
<div class="gf-form-inline">
<div class="gf-form">
<span class="gf-form-label width-9 query-keyword">Service</span>
<stackdriver-picker
onChange="ctrl.handleServiceChange"
selected="ctrl.target.service"
options="ctrl.services"
searchable="false"
placeholder="'Select Services'"
className="'width-15'"
></stackdriver-picker>
</div>
<div class="gf-form gf-form--grow"><div class="gf-form-label gf-form-label--grow"></div></div>
</div>
<div class="gf-form-inline">
<div class="gf-form">
<span class="gf-form-label width-9 query-keyword">Metric</span>
<stackdriver-picker
onChange="ctrl.handleMetricTypeChange"
selected="ctrl.target.metricType"
options="ctrl.getMetricsList()"
template-variables="ctrl.templateSrv.variables"
group-name="'Metric Types'"
searchable="true"
placeholder="'Select Metric'"
className="'width-15'"
></stackdriver-picker>
<!--
<div class="gf-form-inline">
<div class="gf-form">
<span class="gf-form-label width-9 query-keyword">Service</span>
<stackdriver-picker
onChange="ctrl.handleServiceChange"
selected="ctrl.target.service"
options="ctrl.services"
searchable="false"
placeholder="'Select Services'"
className="'width-15'"
></stackdriver-picker>
</div>
<div class="gf-form gf-form--grow"><div class="gf-form-label gf-form-label--grow"></div></div>
</div>
<div class="gf-form-inline">
<div class="gf-form">
<span class="gf-form-label width-9 query-keyword">Metric</span>
<stackdriver-picker
onChange="ctrl.handleMetricTypeChange"
selected="ctrl.target.metricType"
options="ctrl.getMetricsList()"
template-variables="ctrl.templateSrv.variables"
group-name="'Metric Types'"
searchable="true"
placeholder="'Select Metric'"
className="'width-15'"
></stackdriver-picker>
</div>
-->
<div class="gf-form-inline">
<div class="gf-form">
<span class="gf-form-label query-keyword width-9">Filter</span>
@@ -1,5 +1,4 @@
import _ from 'lodash';
import appEvents from 'app/core/app_events';
import { QueryCtrl } from 'app/plugins/sdk';
import './query_aggregation_ctrl';
import './query_filter_ctrl';
@@ -80,42 +79,17 @@ export class StackdriverQueryCtrl extends QueryCtrl {
'groupName',
['templateVariables', { watchDepth: 'reference' }],
]);
// this.handleMetricTypeChange = this.handleMetricTypeChange.bind(this);
// this.handleAggregationChange = this.handleAggregationChange.bind(this);
this.handleTargetChange = this.handleTargetChange.bind(this);
registerAngularDirectives();
// this.getLabels();
this.handleQueryChange = this.handleQueryChange.bind(this);
this.handleExecuteQuery = this.handleExecuteQuery.bind(this);
}
// handleMetricTypeChange({ valueType, metricKind, type, unit }) {
// this.target.metricType = type;
// this.target.unit = unit;
// this.target.valueType = valueType;
// this.target.metricKind = metricKind;
// this.$rootScope.$broadcast('metricTypeChanged');
// this.getLabels();
// this.refresh();
// }
// handleAggregationChange(crossSeriesReducer) {
// this.target.aggregation.crossSeriesReducer = crossSeriesReducer;
// this.refresh();
// }
handleTargetChange(target: Target) {
console.log(target);
handleQueryChange(target: Target) {
Object.assign(this.target, target);
}
async getLabels() {
this.loadLabelsPromise = new Promise(async resolve => {
try {
const { meta } = await this.datasource.getLabels(this.target.metricType, this.target.refId);
this.labelData = meta;
resolve();
} catch (error) {
appEvents.emit('alert-error', ['Error', 'Error loading metric labels for ' + this.target.metricType]);
resolve();
}
});
handleExecuteQuery() {
this.$scope.ctrl.refresh();
}
onDataReceived(dataList) {
@@ -1,8 +1,6 @@
import coreModule from 'app/core/core_module';
import _ from 'lodash';
import { FilterSegments } from './filter_segments';
import { QueryMeta } from './types';
// import appEvents from 'app/core/app_events';
import { FilterSegments, DefaultFilterValue } from './filter_segments';
export class StackdriverFilter {
/** @ngInject */
@@ -16,7 +14,8 @@ export class StackdriverFilter {
labelData: '<',
loading: '<',
target: '=',
refresh: '&',
filtersChanged: '&',
groupBysChanged: '&',
hideGroupBys: '<',
},
};
@@ -24,41 +23,19 @@ export class StackdriverFilter {
}
export class StackdriverFilterCtrl {
metricLabels: { [key: string]: string[] };
resourceLabels: { [key: string]: string[] };
resourceTypes: string[];
defaultRemoveGroupByValue = '-- remove group by --';
resourceTypeValue = 'resource.type';
metricDescriptors: any[];
metrics: any[];
services: any[];
groupBySegments: any[];
filterSegments: FilterSegments;
removeSegment: any;
target: any;
labelData: QueryMeta;
loading: Promise<any>;
/** @ngInject */
constructor(private $scope, private uiSegmentSrv, private templateSrv, private $rootScope) {
this.target = $scope.target;
this.metricDescriptors = [];
this.metrics = [];
this.services = [];
this.$scope = $scope.$parent;
this.target = this.$scope.target;
this.initSegments($scope.hideGroupBys);
this.handleMetricTypeChange = this.handleMetricTypeChange.bind(this);
this.handleServiceChange = this.handleServiceChange.bind(this);
}
handleMetricTypeChange(value) {
this.target.metricType = value;
this.setMetricType();
this.$scope.refresh();
// this.getLabels();
this.initSegments(this.$scope.hideGroupBys);
}
initSegments(hideGroupBys: boolean) {
@@ -71,106 +48,13 @@ export class StackdriverFilterCtrl {
this.removeSegment = this.uiSegmentSrv.newSegment({ fake: true, value: '-- remove group by --' });
// this.filterSegments = new FilterSegments(
// this.uiSegmentSrv,
// this.target,
// this.getFilterKeys.bind(this),
// this.getFilterValues.bind(this)
// );
// this.filterSegments.buildSegmentModel();
}
// async getCurrentProject() {
// return new Promise(async (resolve, reject) => {
// try {
// if (!this.target.defaultProject || this.target.defaultProject === 'loading project...') {
// this.target.defaultProject = await this.datasource.getDefaultProject();
// }
// resolve(this.target.defaultProject);
// } catch (error) {
// appEvents.emit('ds-request-error', error);
// reject();
// }
// });
// }
// async loadMetricDescriptors() {
// if (this.target.defaultProject !== 'loading project...') {
// this.metricDescriptors = await this.datasource.getMetricTypes(this.target.defaultProject);
// this.services = this.getServicesList();
// this.metrics = this.getMetricsList();
// return this.metricDescriptors;
// } else {
// return [];
// }
// }
getServicesList() {
const services = this.metricDescriptors.map(m => ({
value: m.service,
label: _.startCase(m.serviceShortName),
}));
return services.length > 0 ? _.uniqBy(services, s => s.value) : [];
}
getMetricsList() {
const metricsByService = this.metricDescriptors.filter(m => m.service === this.target.service).map(m => ({
service: m.service,
value: m.type,
label: m.displayName,
description: m.description,
}));
if (
metricsByService.length > 0 &&
!metricsByService.some(m => m.value === this.templateSrv.replace(this.target.metricType))
) {
this.target.metricType = metricsByService[0].value;
}
return metricsByService;
}
// async getLabels() {
// this.loadLabelsPromise = new Promise(async resolve => {
// try {
// if (this.target.metricType) {
// const { meta } = await this.datasource.getLabels(this.target.metricType, this.target.refId);
// this.metricLabels = meta.metricLabels;
// this.resourceLabels = meta.resourceLabels;
// this.resourceTypes = meta.resourceTypes;
// resolve();
// } else {
// resolve();
// }
// } catch (error) {
// appEvents.emit('alert-error', ['Error', 'Error loading metric labels for ' + this.target.metricType]);
// resolve();
// }
// });
// }
handleServiceChange(service) {
this.target.service = service;
this.metrics = this.getMetricsList();
this.setMetricType();
// this.getLabels();
if (!this.metrics.some(m => m.value === this.target.metricType)) {
this.target.metricType = '';
} else {
this.$scope.refresh();
}
}
setMetricType() {
const metric = this.metricDescriptors.find(m => m.type === this.templateSrv.replace(this.target.metricType));
if (metric) {
const { valueType, metricKind, unit } = metric;
this.target.unit = unit;
this.target.valueType = valueType;
this.target.metricKind = metricKind;
this.$rootScope.$broadcast('metricTypeChanged');
}
this.filterSegments = new FilterSegments(
this.uiSegmentSrv,
this.target,
this.getFilterKeys.bind(this),
this.getFilterValues.bind(this)
);
this.filterSegments.buildSegmentModel();
}
async createLabelKeyElements() {
@@ -251,10 +135,10 @@ export class StackdriverFilterCtrl {
return memo;
};
this.target.aggregation.groupBys = this.groupBySegments.reduce(reducer, []);
const groupBys = this.groupBySegments.reduce(reducer, []);
this.$scope.groupBysChanged(groupBys);
this.ensurePlusButton(this.groupBySegments);
this.$rootScope.$broadcast('metricTypeChanged');
this.$scope.refresh();
}
async getFilters(segment, index) {
@@ -291,8 +175,10 @@ export class StackdriverFilterCtrl {
}
filterSegmentUpdated(segment, index) {
this.target.filters = this.filterSegments.filterSegmentUpdated(segment, index);
this.$scope.refresh();
const filters = this.filterSegments.filterSegmentUpdated(segment, index);
if (!filters.some(f => f === DefaultFilterValue)) {
this.$scope.filtersChanged(filters);
}
}
ensurePlusButton(segments) {