use render props pattern
This commit is contained in:
@@ -11,8 +11,10 @@ import { StackdriverPicker } from './StackdriverPicker';
|
||||
export interface Props {
|
||||
onChange: (metricDescriptor) => void;
|
||||
templateSrv: any;
|
||||
valueType: string;
|
||||
metricKind: string;
|
||||
metricDescriptor: {
|
||||
valueType: string;
|
||||
metricKind: string;
|
||||
};
|
||||
aggregation: {
|
||||
crossSeriesReducer: string;
|
||||
alignmentPeriod: string;
|
||||
@@ -39,26 +41,31 @@ export class Aggregations extends React.Component<Props, State> {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.setAggOptions(this.props);
|
||||
if (this.props.metricDescriptor !== null) {
|
||||
this.setAggOptions(this.props);
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps: Props) {
|
||||
const { valueType, metricKind, aggregation } = this.props;
|
||||
if (
|
||||
nextProps.valueType !== valueType ||
|
||||
nextProps.metricKind !== metricKind ||
|
||||
nextProps.aggregation.groupBys !== aggregation.groupBys
|
||||
) {
|
||||
// const { metricDescriptor, aggregation } = this.props;
|
||||
// if (
|
||||
// (metricDescriptor !== null && nextProps.metricDescriptor.valueType !== metricDescriptor.valueType) ||
|
||||
// nextProps.metricDescriptor.metricKind !== metricDescriptor.metricKind ||
|
||||
// nextProps.aggregation.groupBys !== aggregation.groupBys
|
||||
// ) {
|
||||
if (nextProps.metricDescriptor !== null) {
|
||||
this.setAggOptions(nextProps);
|
||||
}
|
||||
}
|
||||
|
||||
setAggOptions({ valueType, metricKind, aggregation }) {
|
||||
setAggOptions({ metricDescriptor, aggregation }) {
|
||||
const { templateSrv } = this.props;
|
||||
let aggregations = getAggregationOptionsByMetric(valueType, metricKind).map(a => ({
|
||||
...a,
|
||||
label: a.text,
|
||||
}));
|
||||
let aggregations = getAggregationOptionsByMetric(metricDescriptor.valueType, metricDescriptor.metricKind).map(
|
||||
a => ({
|
||||
...a,
|
||||
label: a.text,
|
||||
})
|
||||
);
|
||||
|
||||
if (
|
||||
aggregations.length > 0 &&
|
||||
@@ -75,7 +82,10 @@ export class Aggregations extends React.Component<Props, State> {
|
||||
}
|
||||
|
||||
deselectAggregationOption(notValidOptionValue: string) {
|
||||
const aggregations = getAggregationOptionsByMetric(this.props.valueType, this.props.metricKind);
|
||||
const aggregations = getAggregationOptionsByMetric(
|
||||
this.props.metricDescriptor.valueType,
|
||||
this.props.metricDescriptor.metricKind
|
||||
);
|
||||
const newValue = aggregations.find(o => o.value !== notValidOptionValue);
|
||||
this.handleAggregationChange(newValue ? newValue.value : '');
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React from 'react';
|
||||
import _ from 'lodash';
|
||||
import appEvents from 'app/core/app_events';
|
||||
|
||||
import { QueryMeta, Target } from '../types';
|
||||
import { getAngularLoader, AngularComponent } from 'app/core/services/AngularLoader';
|
||||
@@ -8,14 +9,19 @@ import '../query_filter_ctrl';
|
||||
export interface Props {
|
||||
filtersChanged: (filters) => void;
|
||||
groupBysChanged: (groupBys) => void;
|
||||
metricType: string;
|
||||
templateSrv: any;
|
||||
labelData: QueryMeta;
|
||||
loading: Promise<any>;
|
||||
target: Target;
|
||||
uiSegmentSrv: any;
|
||||
datasource: any;
|
||||
}
|
||||
|
||||
export class Filter extends React.Component<Props, any> {
|
||||
interface State {
|
||||
labelData: QueryMeta;
|
||||
loading: Promise<any>;
|
||||
}
|
||||
|
||||
export class Filter extends React.Component<Props, State> {
|
||||
element: any;
|
||||
component: AngularComponent;
|
||||
|
||||
@@ -24,13 +30,13 @@ export class Filter extends React.Component<Props, any> {
|
||||
return;
|
||||
}
|
||||
|
||||
const { loading, labelData, target, filtersChanged, groupBysChanged } = this.props;
|
||||
const { target, filtersChanged, groupBysChanged } = this.props;
|
||||
const loader = getAngularLoader();
|
||||
const template = '<stackdriver-filter> </stackdriver-filter>';
|
||||
|
||||
const scopeProps = {
|
||||
loading,
|
||||
labelData,
|
||||
loading: this.loadLabels.bind(this),
|
||||
labelData: null,
|
||||
target,
|
||||
filtersChanged,
|
||||
groupBysChanged,
|
||||
@@ -39,11 +45,11 @@ export class Filter extends React.Component<Props, any> {
|
||||
this.component = loader.load(this.element, scopeProps, template);
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
const scope = this.component.getScope();
|
||||
scope.loading = _.clone(this.props.loading);
|
||||
scope.labelData = _.cloneDeep(this.props.labelData);
|
||||
scope.target = _.cloneDeep(this.props.target);
|
||||
componentDidUpdate(prevProps: Props) {
|
||||
if (prevProps.metricType !== this.props.metricType) {
|
||||
const scope = this.component.getScope();
|
||||
scope.loading = this.loadLabels(scope);
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
@@ -52,6 +58,19 @@ export class Filter extends React.Component<Props, any> {
|
||||
}
|
||||
}
|
||||
|
||||
async loadLabels(scope) {
|
||||
return new Promise(async resolve => {
|
||||
try {
|
||||
const { meta } = await this.props.datasource.getLabels(this.props.target.metricType, this.props.target.refId);
|
||||
scope.labelData = meta;
|
||||
resolve();
|
||||
} catch (error) {
|
||||
appEvents.emit('alert-error', ['Error', 'Error loading metric labels for ' + this.props.target.metricType]);
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return <div ref={element => (this.element = element)} style={{ width: '100%' }} />;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ export interface Props {
|
||||
datasource: any;
|
||||
defaultProject: string;
|
||||
metricType: string;
|
||||
children?: (renderProps: any) => JSX.Element;
|
||||
}
|
||||
|
||||
interface State {
|
||||
@@ -17,6 +18,7 @@ interface State {
|
||||
services: any[];
|
||||
service: string;
|
||||
metric: string;
|
||||
metricDescriptor: any;
|
||||
}
|
||||
|
||||
export class Metrics extends React.Component<Props, State> {
|
||||
@@ -26,6 +28,7 @@ export class Metrics extends React.Component<Props, State> {
|
||||
services: [],
|
||||
service: '',
|
||||
metric: '',
|
||||
metricDescriptor: null,
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
@@ -68,13 +71,16 @@ export class Metrics extends React.Component<Props, 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 });
|
||||
const metricDescriptor = this.getSelectedMetricDescriptor(this.props.metricType);
|
||||
this.setState({ metricDescriptors, services, metrics, service: service, metricDescriptor });
|
||||
}
|
||||
|
||||
getSelectedMetricDescriptor(metricType) {
|
||||
return this.state.metricDescriptors.find(md => md.type === this.props.templateSrv.replace(metricType));
|
||||
}
|
||||
|
||||
getMetricsList(metricDescriptors) {
|
||||
const selectedMetricDescriptor = metricDescriptors.find(
|
||||
md => md.type === this.props.templateSrv.replace(this.props.metricType)
|
||||
);
|
||||
const selectedMetricDescriptor = this.getSelectedMetricDescriptor(this.props.metricType);
|
||||
const metricsByService = metricDescriptors.filter(m => m.service === selectedMetricDescriptor.service).map(m => ({
|
||||
service: m.service,
|
||||
value: m.type,
|
||||
@@ -103,8 +109,9 @@ export class Metrics extends React.Component<Props, State> {
|
||||
}
|
||||
|
||||
handleMetricTypeChange(value) {
|
||||
const selectedMetricDescriptor = this.state.metricDescriptors.find(md => md.type === value);
|
||||
this.props.onChange(selectedMetricDescriptor);
|
||||
const metricDescriptor = this.getSelectedMetricDescriptor(value);
|
||||
this.setState({ metricDescriptor });
|
||||
this.props.onChange(metricDescriptor);
|
||||
}
|
||||
|
||||
getServicesList(metricDescriptors) {
|
||||
@@ -166,6 +173,7 @@ export class Metrics extends React.Component<Props, State> {
|
||||
<div className="gf-form-label gf-form-label--grow" />
|
||||
</div>
|
||||
</div>
|
||||
{this.props.children(this.state.metricDescriptor)}
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import React from 'react';
|
||||
import _ from 'lodash';
|
||||
import appEvents from 'app/core/app_events';
|
||||
|
||||
import { Metrics } from './Metrics';
|
||||
import { Filter } from './Filter';
|
||||
import { Aggregations } from './Aggregations';
|
||||
import { Target, QueryMeta } from '../types';
|
||||
import { Target } from '../types';
|
||||
|
||||
export interface Props {
|
||||
onQueryChange: (target: Target) => void;
|
||||
@@ -18,8 +17,6 @@ export interface Props {
|
||||
|
||||
interface State {
|
||||
target: Target;
|
||||
labelData: QueryMeta;
|
||||
loadLabelsPromise: Promise<any>;
|
||||
}
|
||||
|
||||
const DefaultTarget: Target = {
|
||||
@@ -41,85 +38,79 @@ const DefaultTarget: Target = {
|
||||
};
|
||||
|
||||
export class QueryEditor extends React.Component<Props, State> {
|
||||
state: State = { labelData: null, loadLabelsPromise: new Promise(() => {}), target: DefaultTarget };
|
||||
state: State = { target: DefaultTarget };
|
||||
|
||||
componentDidMount() {
|
||||
this.getLabels();
|
||||
this.setState({ target: this.props.target });
|
||||
}
|
||||
|
||||
async getLabels() {
|
||||
const loadLabelsPromise = new Promise(async resolve => {
|
||||
try {
|
||||
const { meta } = await this.props.datasource.getLabels(this.props.target.metricType, this.props.target.refId);
|
||||
this.setState({ labelData: meta });
|
||||
resolve();
|
||||
} catch (error) {
|
||||
appEvents.emit('alert-error', ['Error', 'Error loading metric labels for ' + this.props.target.metricType]);
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
this.setState({ loadLabelsPromise });
|
||||
}
|
||||
|
||||
handleMetricTypeChange({ valueType, metricKind, type, unit }) {
|
||||
this.setState({
|
||||
target: {
|
||||
...this.state.target,
|
||||
...{
|
||||
metricType: type,
|
||||
unit,
|
||||
valueType,
|
||||
metricKind,
|
||||
this.setState(
|
||||
{
|
||||
target: {
|
||||
...this.state.target,
|
||||
...{
|
||||
metricType: type,
|
||||
unit,
|
||||
valueType,
|
||||
metricKind,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// this.$rootScope.$broadcast('metricTypeChanged');
|
||||
this.getLabels();
|
||||
this.props.onQueryChange(this.state.target);
|
||||
this.props.onExecuteQuery();
|
||||
() => {
|
||||
this.props.onQueryChange(this.state.target);
|
||||
this.props.onExecuteQuery();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
handleFilterChange(value) {
|
||||
this.setState({
|
||||
target: {
|
||||
...this.state.target,
|
||||
filters: value,
|
||||
this.setState(
|
||||
{
|
||||
target: {
|
||||
...this.state.target,
|
||||
filters: value,
|
||||
},
|
||||
},
|
||||
});
|
||||
this.props.onQueryChange(this.state.target);
|
||||
this.props.onExecuteQuery();
|
||||
() => {
|
||||
this.props.onQueryChange(this.state.target);
|
||||
this.props.onExecuteQuery();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
handleGroupBysChange(value) {
|
||||
this.setState({
|
||||
target: {
|
||||
...this.state.target,
|
||||
groupBys: value,
|
||||
this.setState(
|
||||
{
|
||||
target: {
|
||||
...this.state.target,
|
||||
groupBys: value,
|
||||
},
|
||||
},
|
||||
});
|
||||
this.props.onQueryChange(this.state.target);
|
||||
this.props.onExecuteQuery();
|
||||
() => {
|
||||
this.props.onQueryChange(this.state.target);
|
||||
this.props.onExecuteQuery();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
handleAggregationChange(value) {
|
||||
this.setState({
|
||||
target: {
|
||||
...this.state.target,
|
||||
aggregation: {
|
||||
...this.state.target.aggregation,
|
||||
crossSeriesReducer: value,
|
||||
},
|
||||
const target = {
|
||||
...this.state.target,
|
||||
aggregation: {
|
||||
...this.state.target.aggregation,
|
||||
crossSeriesReducer: value,
|
||||
},
|
||||
};
|
||||
this.setState({ target }, () => {
|
||||
this.props.onQueryChange(target);
|
||||
this.props.onExecuteQuery();
|
||||
});
|
||||
this.props.onQueryChange(this.state.target);
|
||||
this.props.onExecuteQuery();
|
||||
}
|
||||
|
||||
render() {
|
||||
const { labelData, loadLabelsPromise, target } = this.state;
|
||||
const { defaultProject, metricType, valueType, metricKind, aggregation } = target;
|
||||
const { target } = this.state;
|
||||
const { defaultProject, metricType, aggregation } = target;
|
||||
const { templateSrv, datasource, uiSegmentSrv } = this.props;
|
||||
|
||||
return (
|
||||
@@ -130,46 +121,27 @@ export class QueryEditor extends React.Component<Props, State> {
|
||||
templateSrv={templateSrv}
|
||||
datasource={datasource}
|
||||
onChange={value => this.handleMetricTypeChange(value)}
|
||||
/>
|
||||
<Filter
|
||||
filtersChanged={value => this.handleFilterChange(value)}
|
||||
groupBysChanged={value => this.handleGroupBysChange(value)}
|
||||
target={target}
|
||||
uiSegmentSrv={uiSegmentSrv}
|
||||
labelData={labelData}
|
||||
templateSrv={templateSrv}
|
||||
loading={loadLabelsPromise}
|
||||
/>
|
||||
<Aggregations
|
||||
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"
|
||||
refresh="target.refresh()"
|
||||
loading="target.loadLabelsPromise"
|
||||
label-data="target.labelData"
|
||||
/>
|
||||
<aggregation-picker
|
||||
value-type="target.target.valueType"
|
||||
metric-kind="target.target.metricKind"
|
||||
aggregation="target.target.aggregation"
|
||||
alignment-period="target.lastQueryMeta.alignmentPeriod"
|
||||
refresh="target.refresh()"
|
||||
template-srv="target.templateSrv"
|
||||
datasource="target.datasource"
|
||||
on-change="target.handleAggregationChange"
|
||||
/>
|
||||
|
||||
<stackdriver-aggregation
|
||||
target="target.target"
|
||||
alignment-period="target.lastQueryMeta.alignmentPeriod"
|
||||
refresh="target.refresh()"
|
||||
/> */}
|
||||
>
|
||||
{metric => (
|
||||
<React.Fragment>
|
||||
<Filter
|
||||
filtersChanged={value => this.handleFilterChange(value)}
|
||||
groupBysChanged={value => this.handleGroupBysChange(value)}
|
||||
target={target}
|
||||
uiSegmentSrv={uiSegmentSrv}
|
||||
templateSrv={templateSrv}
|
||||
datasource={datasource}
|
||||
metricType={metric ? metric.type : ''}
|
||||
/>
|
||||
<Aggregations
|
||||
metricDescriptor={metric}
|
||||
templateSrv={templateSrv}
|
||||
aggregation={aggregation}
|
||||
onChange={value => this.handleAggregationChange(value)}
|
||||
/>
|
||||
</React.Fragment>
|
||||
)}
|
||||
</Metrics>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user