mirror of https://github.com/grafana/grafana.git
break out metric picker and filter
This commit is contained in:
parent
7cc42d7c13
commit
ad55be9865
|
|
@ -0,0 +1,181 @@
|
|||
import React from 'react';
|
||||
import _ from 'lodash';
|
||||
|
||||
import { OptionPicker } from './OptionPicker';
|
||||
import { OptionGroupPicker } from './OptionGroupPicker';
|
||||
|
||||
export interface Props {
|
||||
onChange: (metricDescriptor) => void;
|
||||
templateSrv: any;
|
||||
datasource: any;
|
||||
defaultProject: string;
|
||||
metricType: string;
|
||||
}
|
||||
|
||||
interface State {
|
||||
metricDescriptors: any[];
|
||||
metrics: any[];
|
||||
services: any[];
|
||||
service: string;
|
||||
metric: string;
|
||||
}
|
||||
|
||||
export class MetricPicker extends React.Component<Props, State> {
|
||||
state: State = {
|
||||
metricDescriptors: [],
|
||||
metrics: [],
|
||||
services: [],
|
||||
service: '',
|
||||
metric: '',
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.getCurrentProject()
|
||||
.then(this.loadMetricDescriptors.bind(this))
|
||||
.then(this.initializeServiceAndMetrics.bind(this));
|
||||
// .then(this.getLabels.bind(this));
|
||||
}
|
||||
|
||||
async getCurrentProject() {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
if (!this.props.defaultProject || this.props.defaultProject === 'loading project...') {
|
||||
// this.props.defaultProject = await this.props.datasource.getDefaultProject();
|
||||
await this.props.datasource.getDefaultProject();
|
||||
}
|
||||
resolve(this.props.defaultProject);
|
||||
} catch (error) {
|
||||
// appEvents.emit('ds-request-error', error);
|
||||
reject();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async loadMetricDescriptors() {
|
||||
if (this.props.defaultProject !== 'loading project...') {
|
||||
const metricDescriptors = await this.props.datasource.getMetricTypes(this.props.defaultProject);
|
||||
this.setState({ metricDescriptors });
|
||||
return metricDescriptors;
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
async initializeServiceAndMetrics() {
|
||||
const { metricDescriptors } = this.state;
|
||||
const services = this.getServicesList(metricDescriptors);
|
||||
const metrics = this.getMetricsList(metricDescriptors);
|
||||
const service = metrics.length > 0 ? metrics[0].service : '';
|
||||
this.setState({ metricDescriptors, services, metrics, service: service });
|
||||
}
|
||||
|
||||
getMetricsList(metricDescriptors) {
|
||||
const selectedMetricDescriptor = metricDescriptors.find(md => md.type === this.props.metricType);
|
||||
const metricsByService = metricDescriptors.filter(m => m.service === selectedMetricDescriptor.service).map(m => ({
|
||||
service: m.service,
|
||||
value: m.type,
|
||||
label: m.displayName,
|
||||
description: m.description,
|
||||
}));
|
||||
return metricsByService;
|
||||
}
|
||||
|
||||
handleServiceChange(service) {
|
||||
console.log('handleServiceChange', service);
|
||||
const { metricDescriptors } = this.state;
|
||||
const { templateSrv, metricType } = this.props;
|
||||
|
||||
const metrics = metricDescriptors.filter(m => m.service === templateSrv.replace(service)).map(m => ({
|
||||
service: m.service,
|
||||
value: m.type,
|
||||
label: m.displayName,
|
||||
description: m.description,
|
||||
}));
|
||||
|
||||
this.setState({ service, metrics });
|
||||
|
||||
if (metrics.length > 0 && !metrics.some(m => m.value === templateSrv.replace(metricType))) {
|
||||
this.handleMetricTypeChange(metrics[0].value);
|
||||
}
|
||||
}
|
||||
|
||||
handleMetricTypeChange(value) {
|
||||
const selectedMetricDescriptor = this.state.metricDescriptors.find(md => md.type === value);
|
||||
this.props.onChange(selectedMetricDescriptor);
|
||||
}
|
||||
|
||||
getServicesList(metricDescriptors) {
|
||||
const services = metricDescriptors.map(m => ({
|
||||
value: m.service,
|
||||
label: _.startCase(m.serviceShortName),
|
||||
}));
|
||||
|
||||
return services.length > 0 ? _.uniqBy(services, s => s.value) : [];
|
||||
}
|
||||
|
||||
getTemplateVariablesGroup() {
|
||||
return {
|
||||
label: 'Template Variables',
|
||||
options: this.props.templateSrv.variables.map(v => ({
|
||||
label: `$${v.name}`,
|
||||
value: `$${v.name}`,
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
getMetricGroups() {
|
||||
return [
|
||||
this.getTemplateVariablesGroup(),
|
||||
{
|
||||
label: 'Metrics',
|
||||
options: this.state.metrics,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
render() {
|
||||
const { services, service } = this.state;
|
||||
const { metricType } = this.props;
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<div className="gf-form-inline">
|
||||
<div className="gf-form">
|
||||
<span className="gf-form-label width-9 query-keyword">Service</span>
|
||||
<OptionPicker
|
||||
onChange={value => this.handleServiceChange(value)}
|
||||
selected={service}
|
||||
options={services}
|
||||
searchable={false}
|
||||
placeholder="Select Services"
|
||||
className="width-15"
|
||||
/>
|
||||
</div>
|
||||
<div className="gf-form gf-form--grow">
|
||||
<div className="gf-form-label gf-form-label--grow" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="gf-form-inline">
|
||||
<div className="gf-form">
|
||||
<span className="gf-form-label width-9 query-keyword">Metric</span>
|
||||
<OptionGroupPicker
|
||||
onChange={value => this.handleMetricTypeChange(value)}
|
||||
selected={metricType}
|
||||
groups={this.getMetricGroups()}
|
||||
searchable={true}
|
||||
placeholder="Select Metric"
|
||||
className="width-15"
|
||||
/>
|
||||
</div>
|
||||
<div className="gf-form gf-form--grow">
|
||||
<div className="gf-form-label gf-form-label--grow" />
|
||||
</div>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,11 @@
|
|||
<query-editor-row query-ctrl="ctrl" has-text-edit-mode="false">
|
||||
<stackdriver-filter target="ctrl.target" refresh="ctrl.refresh()" datasource="ctrl.datasource"
|
||||
<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>
|
||||
<stackdriver-aggregation target="ctrl.target" alignment-period="ctrl.lastQueryMeta.alignmentPeriod" refresh="ctrl.refresh()"></stackdriver-aggregation>
|
||||
<!-- <stackdriver-filter target="ctrl.target" refresh="ctrl.refresh()" datasource="ctrl.datasource"
|
||||
></stackdriver-filter>
|
||||
<stackdriver-aggregation target="ctrl.target" alignment-period="ctrl.lastQueryMeta.alignmentPeriod" refresh="ctrl.refresh()"></stackdriver-aggregation> -->
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label query-keyword width-9">Alias By</span>
|
||||
|
|
|
|||
|
|
@ -1,31 +1,33 @@
|
|||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label width-9 query-keyword">Service</span>
|
||||
<option-picker
|
||||
onChange="ctrl.handleServiceChange"
|
||||
selected="ctrl.target.service"
|
||||
options="ctrl.services"
|
||||
searchable="false"
|
||||
placeholder="'Select Services'"
|
||||
className="'width-15'"
|
||||
></option-picker>
|
||||
<!--
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label width-9 query-keyword">Service</span>
|
||||
<option-picker
|
||||
onChange="ctrl.handleServiceChange"
|
||||
selected="ctrl.target.service"
|
||||
options="ctrl.services"
|
||||
searchable="false"
|
||||
placeholder="'Select Services'"
|
||||
className="'width-15'"
|
||||
></option-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 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>
|
||||
<option-group-picker
|
||||
onChange="ctrl.handleMetricTypeChange"
|
||||
selected="ctrl.target.metricType"
|
||||
groups="ctrl.getMetricGroups()"
|
||||
searchable="true"
|
||||
placeholder="'Select Metric'"
|
||||
className="'width-15'"
|
||||
></option-group-picker>
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label width-9 query-keyword">Metric</span>
|
||||
<option-group-picker
|
||||
onChange="ctrl.handleMetricTypeChange"
|
||||
selected="ctrl.target.metricType"
|
||||
groups="ctrl.getMetricGroups()"
|
||||
searchable="true"
|
||||
placeholder="'Select Metric'"
|
||||
className="'width-15'"
|
||||
></option-group-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 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 query-keyword width-9">Filter</span>
|
||||
|
|
|
|||
|
|
@ -52,7 +52,6 @@ export class StackdriverAggregationCtrl {
|
|||
}
|
||||
|
||||
setAlignOptions() {
|
||||
console.log('this.target.metricKind', this.target.metricKind);
|
||||
const alignments = getAlignmentOptionsByMetric(this.target.valueType, this.target.metricKind).map(a => ({
|
||||
...a,
|
||||
label: a.text,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
import _ from 'lodash';
|
||||
import appEvents from 'app/core/app_events';
|
||||
import { QueryCtrl } from 'app/plugins/sdk';
|
||||
import './query_aggregation_ctrl';
|
||||
import './query_filter_ctrl';
|
||||
import { MetricPicker } from './components/MetricPicker';
|
||||
import { OptionPicker } from './components/OptionPicker';
|
||||
import { OptionGroupPicker } from './components/OptionGroupPicker';
|
||||
import { react2AngularDirective } from 'app/core/utils/react2angular';
|
||||
|
|
@ -57,13 +59,19 @@ export class StackdriverQueryCtrl extends QueryCtrl {
|
|||
showLastQuery: boolean;
|
||||
lastQueryMeta: QueryMeta;
|
||||
lastQueryError?: string;
|
||||
labelData: QueryMeta;
|
||||
|
||||
loadLabelsPromise: Promise<any>;
|
||||
templateSrv: any;
|
||||
|
||||
/** @ngInject */
|
||||
constructor($scope, $injector) {
|
||||
constructor($scope, $injector, templateSrv, private $rootScope) {
|
||||
super($scope, $injector);
|
||||
this.templateSrv = templateSrv;
|
||||
_.defaultsDeep(this.target, this.defaults);
|
||||
this.panelCtrl.events.on('data-received', this.onDataReceived.bind(this), $scope);
|
||||
this.panelCtrl.events.on('data-error', this.onDataError.bind(this), $scope);
|
||||
this.handleMetricTypeChange = this.handleMetricTypeChange.bind(this);
|
||||
react2AngularDirective('optionPicker', OptionPicker, [
|
||||
'options',
|
||||
'onChange',
|
||||
|
|
@ -80,6 +88,43 @@ export class StackdriverQueryCtrl extends QueryCtrl {
|
|||
'className',
|
||||
'placeholder',
|
||||
]);
|
||||
react2AngularDirective('metricPicker', MetricPicker, [
|
||||
'target',
|
||||
['onChange', { watchDepth: 'reference' }],
|
||||
'defaultProject',
|
||||
'metricType',
|
||||
['templateSrv', { watchDepth: 'reference' }],
|
||||
['datasource', { watchDepth: 'reference' }],
|
||||
]);
|
||||
this.getLabels();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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) {
|
||||
if (error.data && error.data.message) {
|
||||
console.log(error.data.message);
|
||||
} else {
|
||||
console.log(error);
|
||||
}
|
||||
appEvents.emit('alert-error', ['Error', 'Error loading metric labels for ' + this.target.metricType]);
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onDataReceived(dataList) {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
import coreModule from 'app/core/core_module';
|
||||
import _ from 'lodash';
|
||||
import { FilterSegments } from './filter_segments';
|
||||
import appEvents from 'app/core/app_events';
|
||||
import { QueryMeta } from './query_ctrl';
|
||||
// import appEvents from 'app/core/app_events';
|
||||
|
||||
export class StackdriverFilter {
|
||||
/** @ngInject */
|
||||
|
|
@ -12,8 +13,9 @@ export class StackdriverFilter {
|
|||
controllerAs: 'ctrl',
|
||||
restrict: 'E',
|
||||
scope: {
|
||||
labelData: '<',
|
||||
loading: '<',
|
||||
target: '=',
|
||||
datasource: '=',
|
||||
refresh: '&',
|
||||
hideGroupBys: '<',
|
||||
},
|
||||
|
|
@ -28,41 +30,26 @@ export class StackdriverFilterCtrl {
|
|||
|
||||
defaultRemoveGroupByValue = '-- remove group by --';
|
||||
resourceTypeValue = 'resource.type';
|
||||
loadLabelsPromise: Promise<any>;
|
||||
|
||||
metricDescriptors: any[];
|
||||
metrics: any[];
|
||||
metricGroups: any[];
|
||||
services: any[];
|
||||
groupBySegments: any[];
|
||||
filterSegments: FilterSegments;
|
||||
removeSegment: any;
|
||||
target: any;
|
||||
datasource: any;
|
||||
|
||||
labelData: QueryMeta;
|
||||
loading: Promise<any>;
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private $scope, private uiSegmentSrv, private templateSrv, private $rootScope) {
|
||||
this.datasource = $scope.datasource;
|
||||
this.target = $scope.target;
|
||||
this.metricDescriptors = [];
|
||||
this.metrics = [];
|
||||
this.metricGroups = [];
|
||||
this.services = [];
|
||||
|
||||
this.getCurrentProject()
|
||||
.then(this.loadMetricDescriptors.bind(this))
|
||||
.then(this.getLabels.bind(this));
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
initSegments(hideGroupBys: boolean) {
|
||||
|
|
@ -84,129 +71,34 @@ export class StackdriverFilterCtrl {
|
|||
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();
|
||||
this.metricGroups = this.getMetricGroups();
|
||||
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) : [];
|
||||
}
|
||||
|
||||
getMetricGroups() {
|
||||
return [
|
||||
this.getTemplateVariablesGroup(),
|
||||
{
|
||||
label: 'Metrics',
|
||||
options: this.getMetricsList(),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
getTemplateVariablesGroup() {
|
||||
return {
|
||||
label: 'Template Variables',
|
||||
options: this.templateSrv.variables.map(v => ({
|
||||
label: `$${v.name}`,
|
||||
value: `$${v.name}`,
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
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) {
|
||||
if (error.data && error.data.message) {
|
||||
console.log(error.data.message);
|
||||
} else {
|
||||
console.log(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.metricGroups = this.getMetricGroups();
|
||||
this.setMetricType();
|
||||
this.getLabels();
|
||||
if (!this.metrics.some(m => m.value === this.target.metricType)) {
|
||||
this.target.metricType = '';
|
||||
} else {
|
||||
this.$scope.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
setMetricType() {
|
||||
const { valueType, metricKind, unit } = this.metricDescriptors.find(
|
||||
m => m.type === this.templateSrv.replace(this.target.metricType)
|
||||
);
|
||||
this.target.unit = unit;
|
||||
this.target.valueType = valueType;
|
||||
this.target.metricKind = metricKind;
|
||||
this.$rootScope.$broadcast('metricTypeChanged');
|
||||
}
|
||||
// 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.$scope.labelData.metricLabels = meta.metricLabels;
|
||||
// this.$scope.labelData.resourceLabels = meta.resourceLabels;
|
||||
// this.$scope.labelData.resourceTypes = meta.resourceTypes;
|
||||
// resolve();
|
||||
// } else {
|
||||
// resolve();
|
||||
// }
|
||||
// } catch (error) {
|
||||
// if (error.data && error.data.message) {
|
||||
// console.log(error.data.message);
|
||||
// } else {
|
||||
// console.log(error);
|
||||
// }
|
||||
// appEvents.emit('alert-error', ['Error', 'Error loading metric labels for ' + this.target.metricType]);
|
||||
// resolve();
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
async createLabelKeyElements() {
|
||||
await this.loadLabelsPromise;
|
||||
await this.$scope.loading;
|
||||
|
||||
let elements = Object.keys(this.metricLabels || {}).map(l => {
|
||||
let elements = Object.keys(this.$scope.labelData.metricLabels || {}).map(l => {
|
||||
return this.uiSegmentSrv.newSegment({
|
||||
value: `metric.label.${l}`,
|
||||
expandable: false,
|
||||
|
|
@ -215,7 +107,7 @@ export class StackdriverFilterCtrl {
|
|||
|
||||
elements = [
|
||||
...elements,
|
||||
...Object.keys(this.resourceLabels || {}).map(l => {
|
||||
...Object.keys(this.$scope.labelData.resourceLabels || {}).map(l => {
|
||||
return this.uiSegmentSrv.newSegment({
|
||||
value: `resource.label.${l}`,
|
||||
expandable: false,
|
||||
|
|
@ -223,7 +115,7 @@ export class StackdriverFilterCtrl {
|
|||
}),
|
||||
];
|
||||
|
||||
if (this.resourceTypes && this.resourceTypes.length > 0) {
|
||||
if (this.$scope.labelData.resourceTypes && this.$scope.labelData.resourceTypes.length > 0) {
|
||||
elements = [
|
||||
...elements,
|
||||
this.uiSegmentSrv.newSegment({
|
||||
|
|
@ -288,28 +180,33 @@ export class StackdriverFilterCtrl {
|
|||
}
|
||||
|
||||
async getFilters(segment, index) {
|
||||
const hasNoFilterKeys = this.metricLabels && Object.keys(this.metricLabels).length === 0;
|
||||
const hasNoFilterKeys =
|
||||
this.$scope.labelData.metricLabels && Object.keys(this.$scope.labelData.metricLabels).length === 0;
|
||||
return this.filterSegments.getFilters(segment, index, hasNoFilterKeys);
|
||||
}
|
||||
|
||||
getFilterValues(index) {
|
||||
const filterKey = this.templateSrv.replace(this.filterSegments.filterSegments[index - 2].value);
|
||||
if (!filterKey || !this.metricLabels || Object.keys(this.metricLabels).length === 0) {
|
||||
if (
|
||||
!filterKey ||
|
||||
!this.$scope.labelData.metricLabels ||
|
||||
Object.keys(this.$scope.labelData.metricLabels).length === 0
|
||||
) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const shortKey = filterKey.substring(filterKey.indexOf('.label.') + 7);
|
||||
|
||||
if (filterKey.startsWith('metric.label.') && this.metricLabels.hasOwnProperty(shortKey)) {
|
||||
return this.metricLabels[shortKey];
|
||||
if (filterKey.startsWith('metric.label.') && this.$scope.labelData.metricLabels.hasOwnProperty(shortKey)) {
|
||||
return this.$scope.labelData.metricLabels[shortKey];
|
||||
}
|
||||
|
||||
if (filterKey.startsWith('resource.label.') && this.resourceLabels.hasOwnProperty(shortKey)) {
|
||||
return this.resourceLabels[shortKey];
|
||||
if (filterKey.startsWith('resource.label.') && this.$scope.labelData.resourceLabels.hasOwnProperty(shortKey)) {
|
||||
return this.$scope.labelData.resourceLabels[shortKey];
|
||||
}
|
||||
|
||||
if (filterKey === this.resourceTypeValue) {
|
||||
return this.resourceTypes;
|
||||
return this.$scope.labelData.resourceTypes;
|
||||
}
|
||||
|
||||
return [];
|
||||
|
|
|
|||
|
|
@ -0,0 +1,330 @@
|
|||
// import coreModule from 'app/core/core_module';
|
||||
// import _ from 'lodash';
|
||||
// import { FilterSegments } from './filter_segments';
|
||||
// import appEvents from 'app/core/app_events';
|
||||
|
||||
// export class StackdriverFilter {
|
||||
// /** @ngInject */
|
||||
// constructor() {
|
||||
// return {
|
||||
// templateUrl: 'public/app/plugins/datasource/stackdriver/partials/query.filter.html',
|
||||
// controller: 'StackdriverFilterCtrl',
|
||||
// controllerAs: 'ctrl',
|
||||
// restrict: 'E',
|
||||
// scope: {
|
||||
// target: '=',
|
||||
// datasource: '=',
|
||||
// refresh: '&',
|
||||
// hideGroupBys: '<',
|
||||
// },
|
||||
// };
|
||||
// }
|
||||
// }
|
||||
|
||||
// export class StackdriverFilterCtrl {
|
||||
// metricLabels: { [key: string]: string[] };
|
||||
// resourceLabels: { [key: string]: string[] };
|
||||
// resourceTypes: string[];
|
||||
|
||||
// defaultRemoveGroupByValue = '-- remove group by --';
|
||||
// resourceTypeValue = 'resource.type';
|
||||
// loadLabelsPromise: Promise<any>;
|
||||
|
||||
// metricDescriptors: any[];
|
||||
// metrics: any[];
|
||||
// services: any[];
|
||||
// groupBySegments: any[];
|
||||
// filterSegments: FilterSegments;
|
||||
// removeSegment: any;
|
||||
// target: any;
|
||||
// datasource: any;
|
||||
|
||||
// /** @ngInject */
|
||||
// constructor(private $scope, private uiSegmentSrv, private templateSrv, private $rootScope) {
|
||||
// this.datasource = $scope.datasource;
|
||||
// this.target = $scope.target;
|
||||
// this.metricDescriptors = [];
|
||||
// this.metrics = [];
|
||||
// this.services = [];
|
||||
|
||||
// this.getCurrentProject()
|
||||
// .then(this.loadMetricDescriptors.bind(this))
|
||||
// .then(this.getLabels.bind(this));
|
||||
|
||||
// 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();
|
||||
// }
|
||||
|
||||
// initSegments(hideGroupBys: boolean) {
|
||||
// if (!hideGroupBys) {
|
||||
// this.groupBySegments = this.target.aggregation.groupBys.map(groupBy => {
|
||||
// return this.uiSegmentSrv.getSegmentForValue(groupBy);
|
||||
// });
|
||||
// this.ensurePlusButton(this.groupBySegments);
|
||||
// }
|
||||
|
||||
// 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) : [];
|
||||
// }
|
||||
|
||||
// getMetricGroups() {
|
||||
// return [
|
||||
// this.getTemplateVariablesGroup(),
|
||||
// {
|
||||
// label: 'Metrics',
|
||||
// options: this.getMetricsList(),
|
||||
// },
|
||||
// ];
|
||||
// }
|
||||
|
||||
// getTemplateVariablesGroup() {
|
||||
// return {
|
||||
// label: 'Template Variables',
|
||||
// options: this.templateSrv.variables.map(v => ({
|
||||
// label: `$${v.name}`,
|
||||
// value: `$${v.name}`,
|
||||
// })),
|
||||
// };
|
||||
// }
|
||||
|
||||
// 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) {
|
||||
// if (error.data && error.data.message) {
|
||||
// console.log(error.data.message);
|
||||
// } else {
|
||||
// console.log(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 { valueType, metricKind, unit } = this.metricDescriptors.find(
|
||||
// m => m.type === this.templateSrv.replace(this.target.metricType)
|
||||
// );
|
||||
// this.target.unit = unit;
|
||||
// this.target.valueType = valueType;
|
||||
// this.target.metricKind = metricKind;
|
||||
// this.$rootScope.$broadcast('metricTypeChanged');
|
||||
// }
|
||||
|
||||
// async createLabelKeyElements() {
|
||||
// await this.loadLabelsPromise;
|
||||
|
||||
// let elements = Object.keys(this.metricLabels || {}).map(l => {
|
||||
// return this.uiSegmentSrv.newSegment({
|
||||
// value: `metric.label.${l}`,
|
||||
// expandable: false,
|
||||
// });
|
||||
// });
|
||||
|
||||
// elements = [
|
||||
// ...elements,
|
||||
// ...Object.keys(this.resourceLabels || {}).map(l => {
|
||||
// return this.uiSegmentSrv.newSegment({
|
||||
// value: `resource.label.${l}`,
|
||||
// expandable: false,
|
||||
// });
|
||||
// }),
|
||||
// ];
|
||||
|
||||
// if (this.resourceTypes && this.resourceTypes.length > 0) {
|
||||
// elements = [
|
||||
// ...elements,
|
||||
// this.uiSegmentSrv.newSegment({
|
||||
// value: this.resourceTypeValue,
|
||||
// expandable: false,
|
||||
// }),
|
||||
// ];
|
||||
// }
|
||||
|
||||
// return elements;
|
||||
// }
|
||||
|
||||
// async getFilterKeys(segment, removeText?: string) {
|
||||
// let elements = await this.createLabelKeyElements();
|
||||
|
||||
// if (this.target.filters.indexOf(this.resourceTypeValue) !== -1) {
|
||||
// elements = elements.filter(e => e.value !== this.resourceTypeValue);
|
||||
// }
|
||||
|
||||
// const noValueOrPlusButton = !segment || segment.type === 'plus-button';
|
||||
// if (noValueOrPlusButton && elements.length === 0) {
|
||||
// return [];
|
||||
// }
|
||||
|
||||
// return [
|
||||
// ...elements,
|
||||
// this.uiSegmentSrv.newSegment({ fake: true, value: removeText || this.defaultRemoveGroupByValue }),
|
||||
// ];
|
||||
// }
|
||||
|
||||
// async getGroupBys(segment) {
|
||||
// let elements = await this.createLabelKeyElements();
|
||||
|
||||
// elements = elements.filter(e => this.target.aggregation.groupBys.indexOf(e.value) === -1);
|
||||
// const noValueOrPlusButton = !segment || segment.type === 'plus-button';
|
||||
// if (noValueOrPlusButton && elements.length === 0) {
|
||||
// return [];
|
||||
// }
|
||||
|
||||
// this.removeSegment.value = this.defaultRemoveGroupByValue;
|
||||
// return [...elements, this.removeSegment];
|
||||
// }
|
||||
|
||||
// groupByChanged(segment, index) {
|
||||
// if (segment.value === this.removeSegment.value) {
|
||||
// this.groupBySegments.splice(index, 1);
|
||||
// } else {
|
||||
// segment.type = 'value';
|
||||
// }
|
||||
|
||||
// const reducer = (memo, seg) => {
|
||||
// if (!seg.fake) {
|
||||
// memo.push(seg.value);
|
||||
// }
|
||||
// return memo;
|
||||
// };
|
||||
|
||||
// this.target.aggregation.groupBys = this.groupBySegments.reduce(reducer, []);
|
||||
// this.ensurePlusButton(this.groupBySegments);
|
||||
// this.$rootScope.$broadcast('metricTypeChanged');
|
||||
// this.$scope.refresh();
|
||||
// }
|
||||
|
||||
// async getFilters(segment, index) {
|
||||
// const hasNoFilterKeys = this.metricLabels && Object.keys(this.metricLabels).length === 0;
|
||||
// return this.filterSegments.getFilters(segment, index, hasNoFilterKeys);
|
||||
// }
|
||||
|
||||
// getFilterValues(index) {
|
||||
// const filterKey = this.templateSrv.replace(this.filterSegments.filterSegments[index - 2].value);
|
||||
// if (!filterKey || !this.metricLabels || Object.keys(this.metricLabels).length === 0) {
|
||||
// return [];
|
||||
// }
|
||||
|
||||
// const shortKey = filterKey.substring(filterKey.indexOf('.label.') + 7);
|
||||
|
||||
// if (filterKey.startsWith('metric.label.') && this.metricLabels.hasOwnProperty(shortKey)) {
|
||||
// return this.metricLabels[shortKey];
|
||||
// }
|
||||
|
||||
// if (filterKey.startsWith('resource.label.') && this.resourceLabels.hasOwnProperty(shortKey)) {
|
||||
// return this.resourceLabels[shortKey];
|
||||
// }
|
||||
|
||||
// if (filterKey === this.resourceTypeValue) {
|
||||
// return this.resourceTypes;
|
||||
// }
|
||||
|
||||
// return [];
|
||||
// }
|
||||
|
||||
// filterSegmentUpdated(segment, index) {
|
||||
// this.target.filters = this.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.uiSegmentSrv.newPlusButton());
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// coreModule.directive('stackdriverFilter', StackdriverFilter);
|
||||
// coreModule.controller('StackdriverFilterCtrl', StackdriverFilterCtrl);
|
||||
|
|
@ -367,12 +367,12 @@ describe('StackdriverQueryFilterCtrl', () => {
|
|||
});
|
||||
|
||||
function createCtrlWithFakes(existingFilters?: string[]) {
|
||||
StackdriverFilterCtrl.prototype.loadMetricDescriptors = () => {
|
||||
return Promise.resolve([]);
|
||||
};
|
||||
StackdriverFilterCtrl.prototype.getLabels = () => {
|
||||
return Promise.resolve();
|
||||
};
|
||||
// StackdriverFilterCtrl.prototype.loadMetricDescriptors = () => {
|
||||
// return Promise.resolve([]);
|
||||
// };
|
||||
// StackdriverFilterCtrl.prototype.getLabels = () => {
|
||||
// return Promise.resolve();
|
||||
// };
|
||||
|
||||
const fakeSegmentServer = {
|
||||
newKey: val => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue