mirror of
https://github.com/grafana/grafana.git
synced 2025-08-06 20:59:35 +08:00

* wip: add slo support * Export DataSourcePlugin * wip: break out metric query editor into its own component * wip: refactor frontend - keep SLO and Metric query in differnt objects * wip - load services and slos * Fix broken test * Add interactive slo expression builder * Change order of dropdowns * Refactoring backend model. slo unit testing in progress * Unit test migration and SLOs * Cleanup SLO editor * Simplify alias by component * Support alias by for slos * Support slos in variable queries * Fix broken last query error * Update Help section to include SLO aliases * streamline datasource resource cache * Break out api specific stuff in datasource to its own file * Move get projects call to frontend * Refactor api caching * Unit test api service * Fix lint go issue * Fix typescript strict errors * Fix test datasource * Use budget fraction selector instead of budget * Reset SLO when service is changed * Handle error in case resource call returned no data * Show real SLI display name * Use unsafe prefix on will mount hook * Store goal in query model since it will be used as soon as graph panel supports adding a threshold * Add comment to describe why componentWillMount is used * Interpolate sloid * Break out SLO aggregation into its own func * Also test group bys for metricquery test * Remove not used type fields * Remove annoying stackdriver prefix from error message * Default view param to FULL * Add part about SLO query builder in docs * Use new images * Fixes after feedback * Add one more group by test * Make stackdriver types internal * Update docs/sources/features/datasources/stackdriver.md Co-Authored-By: Diana Payton <52059945+oddlittlebird@users.noreply.github.com> * Update docs/sources/features/datasources/stackdriver.md Co-Authored-By: Diana Payton <52059945+oddlittlebird@users.noreply.github.com> * Update docs/sources/features/datasources/stackdriver.md Co-Authored-By: Diana Payton <52059945+oddlittlebird@users.noreply.github.com> * Updates after PR feedback * add test for when no alias by defined * fix infinite loop when newVariables feature flag is on onChange being called in componentDidUpdate produces an infinite loop when using the new React template variable implementation. Also fixes a spelling mistake * implements feedback for documentation changes * more doc changes Co-authored-by: Diana Payton <52059945+oddlittlebird@users.noreply.github.com> Co-authored-by: Daniel Lee <dan.limerick@gmail.com>
115 lines
4.2 KiB
TypeScript
115 lines
4.2 KiB
TypeScript
import React, { PureComponent } from 'react';
|
|
import appEvents from 'app/core/app_events';
|
|
import { CoreEvents } from 'app/types';
|
|
import { MetricQueryEditor, QueryTypeSelector, SLOQueryEditor, Help } from './';
|
|
import { StackdriverQuery, MetricQuery, QueryType, SLOQuery } from '../types';
|
|
import { defaultQuery } from './MetricQueryEditor';
|
|
import { defaultQuery as defaultSLOQuery } from './SLOQueryEditor';
|
|
import { toOption, formatStackdriverError } from '../functions';
|
|
import StackdriverDatasource from '../datasource';
|
|
import { ExploreQueryFieldProps } from '@grafana/data';
|
|
|
|
export type Props = ExploreQueryFieldProps<StackdriverDatasource, StackdriverQuery>;
|
|
|
|
interface State {
|
|
lastQueryError: string;
|
|
}
|
|
|
|
export class QueryEditor extends PureComponent<Props, State> {
|
|
state: State = { lastQueryError: '' };
|
|
|
|
async UNSAFE_componentWillMount() {
|
|
const { datasource, query } = this.props;
|
|
|
|
// Unfortunately, migrations like this need to go componentWillMount. As soon as there's
|
|
// migration hook for this module.ts, we can do the migrations there instead.
|
|
if (!this.props.query.hasOwnProperty('metricQuery')) {
|
|
const { hide, refId, datasource, key, queryType, maxLines, metric, ...metricQuery } = this.props.query as any;
|
|
this.props.query.metricQuery = metricQuery;
|
|
}
|
|
|
|
if (!this.props.query.hasOwnProperty('queryType')) {
|
|
this.props.query.queryType = QueryType.METRICS;
|
|
}
|
|
|
|
await datasource.ensureGCEDefaultProject();
|
|
if (!query.metricQuery.projectName) {
|
|
this.props.query.metricQuery.projectName = datasource.getDefaultProject();
|
|
}
|
|
}
|
|
|
|
componentDidMount() {
|
|
appEvents.on(CoreEvents.dsRequestError, this.onDataError.bind(this));
|
|
appEvents.on(CoreEvents.dsRequestResponse, this.onDataResponse.bind(this));
|
|
}
|
|
|
|
componentWillUnmount() {
|
|
appEvents.off(CoreEvents.dsRequestResponse, this.onDataResponse.bind(this));
|
|
appEvents.on(CoreEvents.dsRequestError, this.onDataError.bind(this));
|
|
}
|
|
|
|
onDataResponse() {
|
|
this.setState({ lastQueryError: '' });
|
|
}
|
|
|
|
onDataError(error: any) {
|
|
this.setState({ lastQueryError: formatStackdriverError(error) });
|
|
}
|
|
|
|
onQueryChange(prop: string, value: any) {
|
|
this.props.onChange({ ...this.props.query, [prop]: value });
|
|
this.props.onRunQuery();
|
|
}
|
|
|
|
render() {
|
|
const { datasource, query, onRunQuery, onChange } = this.props;
|
|
const metricQuery = { ...defaultQuery, projectName: datasource.getDefaultProject(), ...query.metricQuery };
|
|
const sloQuery = { ...defaultSLOQuery, projectName: datasource.getDefaultProject(), ...query.sloQuery };
|
|
const queryType = query.queryType || QueryType.METRICS;
|
|
const meta = this.props.data?.series.length ? this.props.data?.series[0].meta : {};
|
|
const usedAlignmentPeriod = meta?.alignmentPeriod as string;
|
|
const variableOptionGroup = {
|
|
label: 'Template Variables',
|
|
expanded: false,
|
|
options: datasource.variables.map(toOption),
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<QueryTypeSelector
|
|
value={queryType}
|
|
templateVariableOptions={variableOptionGroup.options}
|
|
onChange={(queryType: QueryType) => {
|
|
onChange({ ...query, sloQuery, queryType });
|
|
onRunQuery();
|
|
}}
|
|
></QueryTypeSelector>
|
|
|
|
{queryType === QueryType.METRICS && (
|
|
<MetricQueryEditor
|
|
refId={query.refId}
|
|
variableOptionGroup={variableOptionGroup}
|
|
usedAlignmentPeriod={usedAlignmentPeriod}
|
|
onChange={(query: MetricQuery) => this.onQueryChange('metricQuery', query)}
|
|
onRunQuery={onRunQuery}
|
|
datasource={datasource}
|
|
query={metricQuery}
|
|
></MetricQueryEditor>
|
|
)}
|
|
|
|
{queryType === QueryType.SLO && (
|
|
<SLOQueryEditor
|
|
variableOptionGroup={variableOptionGroup}
|
|
usedAlignmentPeriod={usedAlignmentPeriod}
|
|
onChange={(query: SLOQuery) => this.onQueryChange('sloQuery', query)}
|
|
onRunQuery={onRunQuery}
|
|
datasource={datasource}
|
|
query={sloQuery}
|
|
></SLOQueryEditor>
|
|
)}
|
|
<Help rawQuery={decodeURIComponent(meta?.rawQuery ?? '')} lastQueryError={this.state.lastQueryError} />
|
|
</>
|
|
);
|
|
}
|
|
}
|