mirror of
https://github.com/grafana/grafana.git
synced 2026-09-05 04:40:13 -05:00
QueryOptions: Fixed min interval placeholder now is real min interval from data source settings (#24227)
This commit is contained in:
@@ -4,7 +4,7 @@ import React, { PureComponent } from 'react';
|
||||
import { DataSourcePicker } from 'app/core/components/Select/DataSourcePicker';
|
||||
import { QueryOptions } from './QueryOptions';
|
||||
import { Button, CustomScrollbar, HorizontalGroup, Modal, stylesFactory } from '@grafana/ui';
|
||||
import { getLocationSrv } from '@grafana/runtime';
|
||||
import { getLocationSrv, getDataSourceSrv } from '@grafana/runtime';
|
||||
import { QueryEditorRows } from './QueryEditorRows';
|
||||
// Services
|
||||
import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
|
||||
@@ -13,7 +13,14 @@ import config from 'app/core/config';
|
||||
// Types
|
||||
import { PanelModel } from '../state/PanelModel';
|
||||
import { DashboardModel } from '../state/DashboardModel';
|
||||
import { DataQuery, DataSourceSelectItem, DefaultTimeRange, LoadingState, PanelData } from '@grafana/data';
|
||||
import {
|
||||
DataQuery,
|
||||
DataSourceSelectItem,
|
||||
DefaultTimeRange,
|
||||
LoadingState,
|
||||
PanelData,
|
||||
DataSourceApi,
|
||||
} from '@grafana/data';
|
||||
import { PluginHelp } from 'app/core/components/PluginHelp/PluginHelp';
|
||||
import { addQuery } from 'app/core/utils/query';
|
||||
import { Unsubscribable } from 'rxjs';
|
||||
@@ -28,7 +35,8 @@ interface Props {
|
||||
}
|
||||
|
||||
interface State {
|
||||
currentDS: DataSourceSelectItem;
|
||||
dataSource?: DataSourceApi;
|
||||
dataSourceItem: DataSourceSelectItem;
|
||||
helpContent: JSX.Element;
|
||||
isLoadingHelp: boolean;
|
||||
isPickerOpen: boolean;
|
||||
@@ -45,7 +53,7 @@ export class QueriesTab extends PureComponent<Props, State> {
|
||||
|
||||
state: State = {
|
||||
isLoadingHelp: false,
|
||||
currentDS: this.findCurrentDataSource(),
|
||||
dataSourceItem: this.findCurrentDataSource(),
|
||||
helpContent: null,
|
||||
isPickerOpen: false,
|
||||
isAddingMixed: false,
|
||||
@@ -58,13 +66,16 @@ export class QueriesTab extends PureComponent<Props, State> {
|
||||
},
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
async componentDidMount() {
|
||||
const { panel } = this.props;
|
||||
const queryRunner = panel.getQueryRunner();
|
||||
|
||||
this.querySubscription = queryRunner.getData(false).subscribe({
|
||||
next: (data: PanelData) => this.onPanelDataUpdate(data),
|
||||
});
|
||||
|
||||
const ds = await getDataSourceSrv().get(panel.datasource);
|
||||
this.setState({ dataSource: ds });
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
@@ -83,12 +94,12 @@ export class QueriesTab extends PureComponent<Props, State> {
|
||||
return this.datasources.find(datasource => datasource.value === panel.datasource) || this.datasources[0];
|
||||
}
|
||||
|
||||
onChangeDataSource = (datasource: DataSourceSelectItem) => {
|
||||
onChangeDataSource = async (newDsItem: DataSourceSelectItem) => {
|
||||
const { panel } = this.props;
|
||||
const { currentDS } = this.state;
|
||||
const { dataSourceItem } = this.state;
|
||||
|
||||
// switching to mixed
|
||||
if (datasource.meta.mixed) {
|
||||
if (newDsItem.meta.mixed) {
|
||||
// Set the datasource on all targets
|
||||
panel.targets.forEach(target => {
|
||||
if (target.datasource !== ExpressionDatasourceID) {
|
||||
@@ -98,27 +109,32 @@ export class QueriesTab extends PureComponent<Props, State> {
|
||||
}
|
||||
}
|
||||
});
|
||||
} else if (currentDS) {
|
||||
} else if (dataSourceItem) {
|
||||
// if switching from mixed
|
||||
if (currentDS.meta.mixed) {
|
||||
if (dataSourceItem.meta.mixed) {
|
||||
// Remove the explicit datasource
|
||||
for (const target of panel.targets) {
|
||||
if (target.datasource !== ExpressionDatasourceID) {
|
||||
delete target.datasource;
|
||||
}
|
||||
}
|
||||
} else if (currentDS.meta.id !== datasource.meta.id) {
|
||||
} else if (dataSourceItem.meta.id !== newDsItem.meta.id) {
|
||||
// we are changing data source type, clear queries
|
||||
panel.targets = [{ refId: 'A' }];
|
||||
}
|
||||
}
|
||||
|
||||
panel.datasource = datasource.value;
|
||||
panel.refresh();
|
||||
const dataSource = await getDataSourceSrv().get(newDsItem.value);
|
||||
|
||||
this.setState({
|
||||
currentDS: datasource,
|
||||
});
|
||||
panel.datasource = newDsItem.value;
|
||||
|
||||
this.setState(
|
||||
{
|
||||
dataSourceItem: newDsItem,
|
||||
dataSource: dataSource,
|
||||
},
|
||||
() => panel.refresh()
|
||||
);
|
||||
};
|
||||
|
||||
openQueryInspector = () => {
|
||||
@@ -143,7 +159,7 @@ export class QueriesTab extends PureComponent<Props, State> {
|
||||
};
|
||||
|
||||
onAddQueryClick = () => {
|
||||
if (this.state.currentDS.meta.mixed) {
|
||||
if (this.state.dataSourceItem.meta.mixed) {
|
||||
this.setState({ isAddingMixed: true });
|
||||
return;
|
||||
}
|
||||
@@ -163,13 +179,21 @@ export class QueriesTab extends PureComponent<Props, State> {
|
||||
|
||||
renderTopSection(styles: QueriesTabStyls) {
|
||||
const { panel } = this.props;
|
||||
const { currentDS, data } = this.state;
|
||||
const { dataSourceItem, data, dataSource } = this.state;
|
||||
|
||||
if (!dataSource) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className={styles.dataSourceRow}>
|
||||
<div className={styles.dataSourceRowItem}>
|
||||
<DataSourcePicker datasources={this.datasources} onChange={this.onChangeDataSource} current={currentDS} />
|
||||
<DataSourcePicker
|
||||
datasources={this.datasources}
|
||||
onChange={this.onChangeDataSource}
|
||||
current={dataSourceItem}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.dataSourceRowItem}>
|
||||
<Button
|
||||
@@ -180,7 +204,7 @@ export class QueriesTab extends PureComponent<Props, State> {
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.dataSourceRowItemOptions}>
|
||||
<QueryOptions panel={panel} datasource={currentDS} data={data} />
|
||||
<QueryOptions panel={panel} dataSource={dataSource} data={data} />
|
||||
</div>
|
||||
<div className={styles.dataSourceRowItem}>
|
||||
<Button
|
||||
@@ -243,9 +267,9 @@ export class QueriesTab extends PureComponent<Props, State> {
|
||||
|
||||
renderQueries() {
|
||||
const { panel, dashboard } = this.props;
|
||||
const { currentDS, data } = this.state;
|
||||
const { dataSourceItem, data } = this.state;
|
||||
|
||||
if (isSharedDashboardQuery(currentDS.name)) {
|
||||
if (isSharedDashboardQuery(dataSourceItem.name)) {
|
||||
return <DashboardQueryEditor panel={panel} panelData={data} onChange={query => this.onUpdateQueries([query])} />;
|
||||
}
|
||||
|
||||
@@ -253,7 +277,7 @@ export class QueriesTab extends PureComponent<Props, State> {
|
||||
<div aria-label={selectors.components.QueryTab.content}>
|
||||
<QueryEditorRows
|
||||
queries={panel.targets}
|
||||
datasource={currentDS}
|
||||
datasource={dataSourceItem}
|
||||
onChangeQueries={this.onUpdateQueries}
|
||||
onScrollBottom={this.onScrollBottom}
|
||||
panel={panel}
|
||||
@@ -264,9 +288,9 @@ export class QueriesTab extends PureComponent<Props, State> {
|
||||
);
|
||||
}
|
||||
|
||||
renderAddQueryRow(styles: QueriesTabStyls) {
|
||||
const { currentDS, isAddingMixed } = this.state;
|
||||
const showAddButton = !(isAddingMixed || isSharedDashboardQuery(currentDS.name));
|
||||
renderAddQueryRow() {
|
||||
const { dataSourceItem, isAddingMixed } = this.state;
|
||||
const showAddButton = !(isAddingMixed || isSharedDashboardQuery(dataSourceItem.name));
|
||||
|
||||
return (
|
||||
<HorizontalGroup spacing="md" align="flex-start">
|
||||
@@ -305,11 +329,11 @@ export class QueriesTab extends PureComponent<Props, State> {
|
||||
<div className={styles.innerWrapper}>
|
||||
{this.renderTopSection(styles)}
|
||||
<div className={styles.queriesWrapper}>{this.renderQueries()}</div>
|
||||
{this.renderAddQueryRow(styles)}
|
||||
{this.renderAddQueryRow()}
|
||||
|
||||
{isHelpOpen && (
|
||||
<Modal title="Data source help" isOpen={true} onDismiss={this.onCloseHelp}>
|
||||
<PluginHelp plugin={this.state.currentDS.meta} type="query_help" />
|
||||
<PluginHelp plugin={this.state.dataSourceItem.meta} type="query_help" />
|
||||
</Modal>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import React, { PureComponent, ChangeEvent, FocusEvent, ReactText } from 'react';
|
||||
|
||||
// Utils
|
||||
import { rangeUtil, DataSourceSelectItem, PanelData } from '@grafana/data';
|
||||
import { rangeUtil, PanelData, DataSourceApi } from '@grafana/data';
|
||||
|
||||
// Components
|
||||
import {
|
||||
@@ -41,7 +41,7 @@ const emptyToNull = (value: string) => {
|
||||
|
||||
interface Props {
|
||||
panel: PanelModel;
|
||||
datasource: DataSourceSelectItem;
|
||||
dataSource: DataSourceApi;
|
||||
data: PanelData;
|
||||
}
|
||||
|
||||
@@ -125,12 +125,12 @@ export class QueryOptions extends PureComponent<Props, State> {
|
||||
};
|
||||
|
||||
renderCacheTimeoutOption() {
|
||||
const { datasource } = this.props;
|
||||
const { dataSource } = this.props;
|
||||
const { cacheTimeout } = this.state;
|
||||
const tooltip = `If your time series store has a query cache this option can override the default cache timeout. Specify a
|
||||
numeric value in seconds.`;
|
||||
|
||||
if (!datasource.meta.queryOptions?.cacheTimeout) {
|
||||
if (!dataSource.meta.queryOptions?.cacheTimeout) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -197,9 +197,10 @@ export class QueryOptions extends PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
renderIntervalOption() {
|
||||
const { data } = this.props;
|
||||
const { data, dataSource } = this.props;
|
||||
const { interval } = this.state;
|
||||
const realInterval = data.request?.interval;
|
||||
const minIntervalOnDs = dataSource.interval ?? 'No limit';
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -220,7 +221,7 @@ export class QueryOptions extends PureComponent<Props, State> {
|
||||
<Input
|
||||
type="text"
|
||||
className="width-6"
|
||||
placeholder={`${realInterval}`}
|
||||
placeholder={`${minIntervalOnDs}`}
|
||||
name={name}
|
||||
spellCheck={false}
|
||||
onBlur={this.onDataSourceOptionBlur('interval')}
|
||||
|
||||
Reference in New Issue
Block a user