src/VariableQueryEditor.tsx (159 lines of code) (raw):
/**
* Copyright 2022 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React, { PureComponent } from 'react';
import { VariableQueryField } from './Fields';
import { QueryEditorProps } from '@grafana/data';
import { DataSource } from './datasource';
import { CloudLoggingVariableQuery, LogFindQueryScopes, VariableScopeData, CloudLoggingOptions, Query } from './types';
import { getTemplateSrv } from '@grafana/runtime';
export type Props = QueryEditorProps<DataSource, Query, CloudLoggingOptions, CloudLoggingVariableQuery>;
export class CloudLoggingVariableQueryEditor extends PureComponent<Props, VariableScopeData> {
queryTypes: Array<{ value: string; label: string }> = [
{ value: LogFindQueryScopes.Projects, label: 'Projects' },
{ value: LogFindQueryScopes.Buckets, label: 'Buckets' },
{ value: LogFindQueryScopes.Views, label: 'Views' },
];
defaults: VariableScopeData = {
selectedQueryType: this.queryTypes[0].value,
bucketId: '',
viewId: '',
projects: [],
buckets: [],
projectId: '',
loading: true,
};
constructor(props: Props) {
super(props);
this.state = Object.assign(this.defaults, this.props.query);
}
async componentDidMount() {
await this.props.datasource.ensureGCEDefaultProject();
const projectId = this.props.query.projectId || (await this.props.datasource.getDefaultProject());
const projects = (await this.props.datasource.getProjects());
let buckets: string[] = [];
if (!projectId.startsWith('$')) {
buckets = await this.props.datasource.getLogBuckets(projectId);
}
const state: any = {
projects,
buckets,
loading: false,
projectId,
};
this.setState(state, () => this.onPropsChange());
}
onPropsChange = () => {
const { buckets, ...queryModel } = this.state;
this.props.onChange({ ...queryModel, refId: 'CloudLoggingVariableQueryEditor-VariableQuery' });
};
async onQueryTypeChange(queryType: string) {
const state: any = {
selectedQueryType: queryType,
};
this.setState(state);
}
async onProjectChange(projectId: string) {
let buckets: string[] = [];
if (!projectId.startsWith('$')) {
buckets = await this.props.datasource.getLogBuckets(projectId);
}
const state: any = {
buckets,
projectId,
bucketId: '',
viewId: '',
};
this.setState(state, () => this.onPropsChange());
}
async onBucketChange(projectId: string, bucketId: string) {
let views: string[] = [];
if (!bucketId.startsWith('$')) {
views = await this.props.datasource.getLogBucketViews(projectId, bucketId);
}
const state: any = {
views,
projectId,
bucketId,
viewId: '',
};
this.setState(state, () => this.onPropsChange());
}
renderLogScopeSwitch(queryType: string) {
const variableOptionGroup = {
label: 'Template Variables',
expanded: false,
options: getTemplateSrv()
.getVariables()
.map((v: any) => ({
value: `$${v.name}`,
label: `$${v.name}`,
})),
};
switch (queryType) {
case LogFindQueryScopes.Buckets:
return (
<>
<VariableQueryField
allowCustomValue={true}
value={this.state.projectId}
options={[variableOptionGroup, ...this.state.projects.map((v: any) => ({
value: `${v}`,
label: `${v}`,
}))]}
onChange={(value) => this.onProjectChange(value)}
label="Project"
/>
</>
);
case LogFindQueryScopes.Views:
return (
<>
<VariableQueryField
allowCustomValue={true}
value={this.state.projectId}
options={[variableOptionGroup, ...this.state.projects.map((v: any) => ({
value: `${v}`,
label: `${v}`,
}))]}
onChange={(value) => this.onProjectChange(value)}
label="Project"
/>
<VariableQueryField
allowCustomValue={true}
value={this.state.bucketId}
options={[variableOptionGroup, ...this.state.buckets.map((v: any) => ({
value: `${v}`,
label: `${v}`,
}))]}
onChange={(value) => this.onBucketChange(this.state.projectId, value)}
label="Bucket"
/>
</>);
default:
return '';
}
}
render() {
if (this.state.loading) {
return (
<div className="gf-form max-width-21">
<span className="gf-form-label width-10 query-keyword">Logging Scope</span>
<div className="gf-form-select-wrapper max-width-12">
<select className="gf-form-input">
<option>Loading...</option>
</select>
</div>
</div>
);
}
return (
<>
<VariableQueryField
value={this.state.selectedQueryType}
options={this.queryTypes}
onChange={(value) => this.onQueryTypeChange(value)}
label="Logging Scope"
/>
{this.renderLogScopeSwitch(this.state.selectedQueryType)}
</>
);
}
}