grafana/public/app/features/dashboard/components/PanelEditor/PanelEditorQueries.tsx
2024-07-08 13:12:56 +02:00

127 lines
4.1 KiB
TypeScript

import { PureComponent } from 'react';
import { DataQuery, getDataSourceRef } from '@grafana/data';
import { locationService } from '@grafana/runtime';
import { storeLastUsedDataSourceInLocalStorage } from 'app/features/datasources/components/picker/utils';
import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
import { QueryGroup } from 'app/features/query/components/QueryGroup';
import { QueryGroupDataSource, QueryGroupOptions } from 'app/types';
import { getDashboardSrv } from '../../services/DashboardSrv';
import { PanelModel } from '../../state';
import { getLastUsedDatasourceFromStorage } from '../../utils/dashboard';
interface Props {
/** Current panel */
panel: PanelModel;
/** Added here to make component re-render when queries change from outside */
queries: DataQuery[];
}
export class PanelEditorQueries extends PureComponent<Props> {
constructor(props: Props) {
super(props);
}
// store last used datasource in local storage
updateLastUsedDatasource = (datasource: QueryGroupDataSource) => {
storeLastUsedDataSourceInLocalStorage(datasource);
};
buildQueryOptions(panel: PanelModel): QueryGroupOptions {
const dataSource: QueryGroupDataSource = panel.datasource ?? {
default: true,
};
const datasourceSettings = getDatasourceSrv().getInstanceSettings(dataSource);
// store last datasource used in local storage
this.updateLastUsedDatasource(dataSource);
return {
cacheTimeout: datasourceSettings?.meta.queryOptions?.cacheTimeout ? panel.cacheTimeout : undefined,
dataSource: {
default: datasourceSettings?.isDefault,
...(datasourceSettings ? getDataSourceRef(datasourceSettings) : { type: undefined, uid: undefined }),
},
queryCachingTTL: datasourceSettings?.cachingConfig?.enabled ? panel.queryCachingTTL : undefined,
queries: panel.targets,
maxDataPoints: panel.maxDataPoints,
minInterval: panel.interval,
timeRange: {
from: panel.timeFrom,
shift: panel.timeShift,
hide: panel.hideTimeOverride,
},
};
}
async componentDidMount() {
const { panel } = this.props;
// If the panel model has no datasource property load the default data source property and update the persisted model
// Because this part of the panel model is not in redux yet we do a forceUpdate.
if (!panel.datasource) {
let ds;
// check if we have last used datasource from local storage
// get dashboard uid
const dashboardUid = getDashboardSrv().getCurrent()?.uid ?? '';
const lastUsedDatasource = getLastUsedDatasourceFromStorage(dashboardUid!);
// do we have a last used datasource for this dashboard
if (lastUsedDatasource?.datasourceUid !== null) {
// get datasource from uid
ds = getDatasourceSrv().getInstanceSettings(lastUsedDatasource?.datasourceUid);
}
// else load default datasource
if (!ds) {
ds = getDatasourceSrv().getInstanceSettings(null);
}
panel.datasource = getDataSourceRef(ds!);
this.forceUpdate();
}
}
onRunQueries = () => {
this.props.panel.refresh();
};
onOpenQueryInspector = () => {
locationService.partial({
inspect: this.props.panel.id,
inspectTab: 'query',
});
};
onOptionsChange = (options: QueryGroupOptions) => {
const { panel } = this.props;
panel.updateQueries(options);
if (options.dataSource.uid !== panel.datasource?.uid) {
// trigger queries when changing data source
setTimeout(this.onRunQueries, 10);
}
this.forceUpdate();
};
render() {
const { panel } = this.props;
// If no panel data soruce set, wait with render. Will be set to default in componentDidMount
if (!panel.datasource) {
return null;
}
const options = this.buildQueryOptions(panel);
return (
<QueryGroup
options={options}
queryRunner={panel.getQueryRunner()}
onRunQueries={this.onRunQueries}
onOpenQueryInspector={this.onOpenQueryInspector}
onOptionsChange={this.onOptionsChange}
/>
);
}
}