Browse Source

move template variable logic to component

Erik Sundell 7 years ago
parent
commit
9507dfe13c

+ 61 - 13
public/app/plugins/datasource/stackdriver/components/StackdriverPicker.tsx

@@ -9,28 +9,76 @@ export interface Props {
   selected: string;
   selected: string;
   placeholder?: string;
   placeholder?: string;
   className?: string;
   className?: string;
-  groups?: boolean;
+  groupName?: string;
+  templateVariables?: any[];
 }
 }
 
 
-export class StackdriverPicker extends React.Component<Props, any> {
+interface State {
+  options: any[];
+}
+
+export class StackdriverPicker extends React.Component<Props, State> {
+  static defaultProps = {
+    templateVariables: [],
+    options: [],
+    groupName: 'Options',
+  };
+
   constructor(props) {
   constructor(props) {
     super(props);
     super(props);
+    this.state = { options: [] };
   }
   }
 
 
-  extractOptions(options) {
-    return options.length > 0 && options.every(o => o.options) ? _.flatten(options.map(o => o.options)) : options;
+  componentDidMount() {
+    this.setState({ options: this.buildOptions(this.props) });
   }
   }
 
 
-  onChange = item => {
-    const extractedOptions = this.extractOptions(this.props.options);
-    const option = extractedOptions.find(option => option.value === item.value);
-    this.props.onChange(option.value);
-  };
+  componentWillReceiveProps(nextProps) {
+    if (nextProps.options.length > 0 || nextProps.templateVariables.length) {
+      this.setState({ options: this.buildOptions(nextProps) });
+    }
+  }
+
+  shouldComponentUpdate(nextProps) {
+    return (
+      !_.isEqual(nextProps.options, this.props.options) ||
+      !_.isEqual(nextProps.templateVariables, this.props.templateVariables)
+    );
+  }
+
+  buildOptions({ templateVariables = [], groupName = '', options }) {
+    return templateVariables.length > 0
+      ? [
+          this.getTemplateVariablesGroup(),
+          {
+            label: groupName,
+            expanded: true,
+            options,
+          },
+        ]
+      : options;
+  }
+
+  getTemplateVariablesGroup() {
+    return {
+      label: 'Template Variables',
+      options: this.props.templateVariables.map(v => ({
+        label: `$${v.name}`,
+        value: `$${v.name}`,
+      })),
+    };
+  }
+
+  getSelectedOption() {
+    const { options } = this.state;
+    const allOptions = options.every(o => o.options) ? _.flatten(options.map(o => o.options)) : options;
+    return allOptions.find(option => option.value === this.props.selected);
+  }
 
 
   render() {
   render() {
-    const { options, selected, placeholder, className, searchable } = this.props;
-    const extractedOptions = this.extractOptions(options);
-    const selectedOption = extractedOptions.find(option => option.value === selected);
+    const { placeholder, className, searchable, onChange } = this.props;
+    const { options } = this.state;
+    const selectedOption = this.getSelectedOption();
 
 
     return (
     return (
       <Select
       <Select
@@ -38,7 +86,7 @@ export class StackdriverPicker extends React.Component<Props, any> {
         isMulti={false}
         isMulti={false}
         isClearable={false}
         isClearable={false}
         backspaceRemovesValue={false}
         backspaceRemovesValue={false}
-        onChange={this.onChange}
+        onChange={item => onChange(item.value)}
         options={options}
         options={options}
         autoFocus={false}
         autoFocus={false}
         isSearchable={searchable}
         isSearchable={searchable}

+ 3 - 1
public/app/plugins/datasource/stackdriver/partials/query.filter.html

@@ -18,7 +18,9 @@
     <stackdriver-picker
     <stackdriver-picker
       onChange="ctrl.handleMetricTypeChange"
       onChange="ctrl.handleMetricTypeChange"
       selected="ctrl.target.metricType"
       selected="ctrl.target.metricType"
-      options="ctrl.getMetricGroups()"
+      options="ctrl.getMetricsList()"
+      template-variables="ctrl.templateSrv.variables"
+      group-name="'Metric Types'"
       searchable="true"
       searchable="true"
       placeholder="'Select Metric'"
       placeholder="'Select Metric'"
       className="'width-15'"
       className="'width-15'"

+ 10 - 40
public/app/plugins/datasource/stackdriver/query_aggregation_ctrl.ts

@@ -29,16 +29,10 @@ export class StackdriverAggregationCtrl {
   constructor(private $scope, private templateSrv) {
   constructor(private $scope, private templateSrv) {
     this.$scope.ctrl = this;
     this.$scope.ctrl = this;
     this.target = $scope.target;
     this.target = $scope.target;
-    this.alignmentPeriods = [
-      this.getTemplateVariablesGroup(),
-      {
-        label: 'Alignment Periods',
-        options: alignmentPeriods.map(ap => ({
-          ...ap,
-          label: ap.text,
-        })),
-      },
-    ];
+    this.alignmentPeriods = alignmentPeriods.map(ap => ({
+      ...ap,
+      label: ap.text,
+    }));
     this.setAggOptions();
     this.setAggOptions();
     this.setAlignOptions();
     this.setAlignOptions();
     const self = this;
     const self = this;
@@ -52,42 +46,28 @@ export class StackdriverAggregationCtrl {
   }
   }
 
 
   setAlignOptions() {
   setAlignOptions() {
-    const alignments = getAlignmentOptionsByMetric(this.target.valueType, this.target.metricKind).map(a => ({
+    this.alignOptions = getAlignmentOptionsByMetric(this.target.valueType, this.target.metricKind).map(a => ({
       ...a,
       ...a,
       label: a.text,
       label: a.text,
     }));
     }));
-    this.alignOptions = [
-      this.getTemplateVariablesGroup(),
-      {
-        label: 'Alignment Options',
-        options: alignments,
-      },
-    ];
-    if (!alignments.find(o => o.value === this.templateSrv.replace(this.target.aggregation.perSeriesAligner))) {
-      this.target.aggregation.perSeriesAligner = alignments.length > 0 ? alignments[0].value : '';
+    if (!this.alignOptions.find(o => o.value === this.templateSrv.replace(this.target.aggregation.perSeriesAligner))) {
+      this.target.aggregation.perSeriesAligner = this.alignOptions.length > 0 ? this.alignOptions[0].value : '';
     }
     }
   }
   }
 
 
   setAggOptions() {
   setAggOptions() {
-    let aggregations = getAggregationOptionsByMetric(this.target.valueType, this.target.metricKind).map(a => ({
+    this.aggOptions = getAggregationOptionsByMetric(this.target.valueType, this.target.metricKind).map(a => ({
       ...a,
       ...a,
       label: a.text,
       label: a.text,
     }));
     }));
-    if (!aggregations.find(o => o.value === this.templateSrv.replace(this.target.aggregation.crossSeriesReducer))) {
+    if (!this.aggOptions.find(o => o.value === this.templateSrv.replace(this.target.aggregation.crossSeriesReducer))) {
       this.deselectAggregationOption('REDUCE_NONE');
       this.deselectAggregationOption('REDUCE_NONE');
     }
     }
 
 
     if (this.target.aggregation.groupBys.length > 0) {
     if (this.target.aggregation.groupBys.length > 0) {
-      aggregations = aggregations.filter(o => o.value !== 'REDUCE_NONE');
+      this.aggOptions = this.aggOptions.filter(o => o.value !== 'REDUCE_NONE');
       this.deselectAggregationOption('REDUCE_NONE');
       this.deselectAggregationOption('REDUCE_NONE');
     }
     }
-    this.aggOptions = [
-      this.getTemplateVariablesGroup(),
-      {
-        label: 'Aggregations',
-        options: aggregations,
-      },
-    ];
   }
   }
 
 
   handleAlignmentChange(value) {
   handleAlignmentChange(value) {
@@ -120,16 +100,6 @@ export class StackdriverAggregationCtrl {
     const newValue = aggregations.find(o => o.value !== notValidOptionValue);
     const newValue = aggregations.find(o => o.value !== notValidOptionValue);
     this.target.aggregation.crossSeriesReducer = newValue ? newValue.value : '';
     this.target.aggregation.crossSeriesReducer = newValue ? newValue.value : '';
   }
   }
-
-  getTemplateVariablesGroup() {
-    return {
-      label: 'Template Variables',
-      options: this.templateSrv.variables.map(v => ({
-        label: `$${v.name}`,
-        value: `$${v.name}`,
-      })),
-    };
-  }
 }
 }
 
 
 coreModule.directive('stackdriverAggregation', StackdriverAggregation);
 coreModule.directive('stackdriverAggregation', StackdriverAggregation);

+ 2 - 0
public/app/plugins/datasource/stackdriver/query_ctrl.ts

@@ -70,6 +70,8 @@ export class StackdriverQueryCtrl extends QueryCtrl {
       'searchable',
       'searchable',
       'className',
       'className',
       'placeholder',
       'placeholder',
+      'groupName',
+      ['templateVariables', { watchDepth: 'reference' }],
     ]);
     ]);
   }
   }
 
 

+ 8 - 31
public/app/plugins/datasource/stackdriver/query_filter_ctrl.ts

@@ -32,7 +32,6 @@ export class StackdriverFilterCtrl {
 
 
   metricDescriptors: any[];
   metricDescriptors: any[];
   metrics: any[];
   metrics: any[];
-  metricGroups: any[];
   services: any[];
   services: any[];
   groupBySegments: any[];
   groupBySegments: any[];
   filterSegments: FilterSegments;
   filterSegments: FilterSegments;
@@ -46,7 +45,6 @@ export class StackdriverFilterCtrl {
     this.target = $scope.target;
     this.target = $scope.target;
     this.metricDescriptors = [];
     this.metricDescriptors = [];
     this.metrics = [];
     this.metrics = [];
-    this.metricGroups = [];
     this.services = [];
     this.services = [];
 
 
     this.getCurrentProject()
     this.getCurrentProject()
@@ -103,7 +101,6 @@ export class StackdriverFilterCtrl {
       this.metricDescriptors = await this.datasource.getMetricTypes(this.target.defaultProject);
       this.metricDescriptors = await this.datasource.getMetricTypes(this.target.defaultProject);
       this.services = this.getServicesList();
       this.services = this.getServicesList();
       this.metrics = this.getMetricsList();
       this.metrics = this.getMetricsList();
-      this.metricGroups = this.getMetricGroups();
       return this.metricDescriptors;
       return this.metricDescriptors;
     } else {
     } else {
       return [];
       return [];
@@ -119,26 +116,6 @@ export class StackdriverFilterCtrl {
     return services.length > 0 ? _.uniqBy(services, s => s.value) : [];
     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() {
   getMetricsList() {
     const metricsByService = this.metricDescriptors.filter(m => m.service === this.target.service).map(m => ({
     const metricsByService = this.metricDescriptors.filter(m => m.service === this.target.service).map(m => ({
       service: m.service,
       service: m.service,
@@ -183,7 +160,6 @@ export class StackdriverFilterCtrl {
   handleServiceChange(service) {
   handleServiceChange(service) {
     this.target.service = service;
     this.target.service = service;
     this.metrics = this.getMetricsList();
     this.metrics = this.getMetricsList();
-    this.metricGroups = this.getMetricGroups();
     this.setMetricType();
     this.setMetricType();
     this.getLabels();
     this.getLabels();
     if (!this.metrics.some(m => m.value === this.target.metricType)) {
     if (!this.metrics.some(m => m.value === this.target.metricType)) {
@@ -194,13 +170,14 @@ export class StackdriverFilterCtrl {
   }
   }
 
 
   setMetricType() {
   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');
+    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');
+    }
   }
   }
 
 
   async createLabelKeyElements() {
   async createLabelKeyElements() {