mirror of
https://github.com/grafana/grafana.git
synced 2026-07-30 00:08:10 -05:00
PanelEditor: Overrides name matcher still show all original field names even after Field default display name is specified (#24933)
* FieldConfigOverrides: Should not apply defaults in override UI options * Missed change
This commit is contained in:
@@ -35,7 +35,7 @@ export const OptionsPaneContent: React.FC<Props> = ({
|
|||||||
const styles = getStyles(theme);
|
const styles = getStyles(theme);
|
||||||
const [activeTab, setActiveTab] = useState('options');
|
const [activeTab, setActiveTab] = useState('options');
|
||||||
const [isSearching, setSearchMode] = useState(false);
|
const [isSearching, setSearchMode] = useState(false);
|
||||||
const [currentData, hasSeries] = usePanelLatestData(panel);
|
const [currentData, hasSeries] = usePanelLatestData(panel, { withTransforms: true, withFieldConfig: false });
|
||||||
|
|
||||||
const renderFieldOptions = useCallback(
|
const renderFieldOptions = useCallback(
|
||||||
(plugin: PanelPlugin) => {
|
(plugin: PanelPlugin) => {
|
||||||
|
|||||||
@@ -51,11 +51,13 @@ export const OverrideEditor: React.FC<OverrideEditorProps> = ({
|
|||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const matcherUi = fieldMatchersUI.get(override.matcher.id);
|
const matcherUi = fieldMatchersUI.get(override.matcher.id);
|
||||||
const styles = getStyles(theme);
|
const styles = getStyles(theme);
|
||||||
|
|
||||||
const matcherLabel = (
|
const matcherLabel = (
|
||||||
<Label category={['Matcher']} description={matcherUi.description}>
|
<Label category={['Matcher']} description={matcherUi.description}>
|
||||||
{matcherUi.name}
|
{matcherUi.name}
|
||||||
</Label>
|
</Label>
|
||||||
);
|
);
|
||||||
|
|
||||||
const onMatcherConfigChange = useCallback(
|
const onMatcherConfigChange = useCallback(
|
||||||
(matcherConfig: any) => {
|
(matcherConfig: any) => {
|
||||||
override.matcher.options = matcherConfig;
|
override.matcher.options = matcherConfig;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import { FieldConfigSource, GrafanaTheme, PanelData, PanelPlugin } from '@grafana/data';
|
import { FieldConfigSource, GrafanaTheme, PanelPlugin } from '@grafana/data';
|
||||||
import { Button, HorizontalGroup, Icon, RadioButtonGroup, stylesFactory } from '@grafana/ui';
|
import { Button, HorizontalGroup, Icon, RadioButtonGroup, stylesFactory } from '@grafana/ui';
|
||||||
import { css, cx } from 'emotion';
|
import { css, cx } from 'emotion';
|
||||||
import config from 'app/core/config';
|
import config from 'app/core/config';
|
||||||
@@ -42,7 +42,6 @@ interface ConnectedProps {
|
|||||||
location: LocationState;
|
location: LocationState;
|
||||||
plugin?: PanelPlugin;
|
plugin?: PanelPlugin;
|
||||||
panel: PanelModel;
|
panel: PanelModel;
|
||||||
data: PanelData;
|
|
||||||
initDone: boolean;
|
initDone: boolean;
|
||||||
tabs: PanelEditorTab[];
|
tabs: PanelEditorTab[];
|
||||||
uiState: PanelEditorUIState;
|
uiState: PanelEditorUIState;
|
||||||
@@ -183,7 +182,7 @@ export class PanelEditorUnconnected extends PureComponent<Props> {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
renderHorizontalSplit(styles: EditorStyles) {
|
renderHorizontalSplit(styles: EditorStyles) {
|
||||||
const { dashboard, panel, tabs, data, uiState } = this.props;
|
const { dashboard, panel, tabs, uiState } = this.props;
|
||||||
return tabs.length > 0 ? (
|
return tabs.length > 0 ? (
|
||||||
<SplitPane
|
<SplitPane
|
||||||
split="horizontal"
|
split="horizontal"
|
||||||
@@ -198,7 +197,7 @@ export class PanelEditorUnconnected extends PureComponent<Props> {
|
|||||||
>
|
>
|
||||||
{this.renderPanel(styles)}
|
{this.renderPanel(styles)}
|
||||||
<div className={styles.tabsWrapper} aria-label={selectors.components.PanelEditor.DataPane.content}>
|
<div className={styles.tabsWrapper} aria-label={selectors.components.PanelEditor.DataPane.content}>
|
||||||
<PanelEditorTabs panel={panel} dashboard={dashboard} tabs={tabs} onChangeTab={this.onChangeTab} data={data} />
|
<PanelEditorTabs panel={panel} dashboard={dashboard} tabs={tabs} onChangeTab={this.onChangeTab} />
|
||||||
</div>
|
</div>
|
||||||
</SplitPane>
|
</SplitPane>
|
||||||
) : (
|
) : (
|
||||||
@@ -350,7 +349,6 @@ const mapStateToProps: MapStateToProps<ConnectedProps, OwnProps, StoreState> = (
|
|||||||
location: state.location,
|
location: state.location,
|
||||||
plugin: plugin,
|
plugin: plugin,
|
||||||
panel,
|
panel,
|
||||||
data: state.panelEditor.getData(),
|
|
||||||
initDone: state.panelEditor.initDone,
|
initDone: state.panelEditor.initDone,
|
||||||
tabs: getPanelEditorTabs(state.location, plugin),
|
tabs: getPanelEditorTabs(state.location, plugin),
|
||||||
uiState: state.panelEditor.ui,
|
uiState: state.panelEditor.ui,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import React, { useCallback } from 'react';
|
|||||||
import { config } from 'app/core/config';
|
import { config } from 'app/core/config';
|
||||||
import { css } from 'emotion';
|
import { css } from 'emotion';
|
||||||
import { IconName, stylesFactory, Tab, TabContent, TabsBar } from '@grafana/ui';
|
import { IconName, stylesFactory, Tab, TabContent, TabsBar } from '@grafana/ui';
|
||||||
import { DataTransformerConfig, LoadingState, PanelData } from '@grafana/data';
|
import { DataTransformerConfig } from '@grafana/data';
|
||||||
import { PanelEditorTab, PanelEditorTabId } from './types';
|
import { PanelEditorTab, PanelEditorTabId } from './types';
|
||||||
import { DashboardModel } from '../../state';
|
import { DashboardModel } from '../../state';
|
||||||
import { QueriesTab } from '../../panel_editor/QueriesTab';
|
import { QueriesTab } from '../../panel_editor/QueriesTab';
|
||||||
@@ -15,12 +15,12 @@ interface PanelEditorTabsProps {
|
|||||||
dashboard: DashboardModel;
|
dashboard: DashboardModel;
|
||||||
tabs: PanelEditorTab[];
|
tabs: PanelEditorTab[];
|
||||||
onChangeTab: (tab: PanelEditorTab) => void;
|
onChangeTab: (tab: PanelEditorTab) => void;
|
||||||
data: PanelData;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PanelEditorTabs: React.FC<PanelEditorTabsProps> = ({ panel, dashboard, tabs, data, onChangeTab }) => {
|
export const PanelEditorTabs: React.FC<PanelEditorTabsProps> = ({ panel, dashboard, tabs, onChangeTab }) => {
|
||||||
const styles = getPanelEditorTabsStyles();
|
const styles = getPanelEditorTabsStyles();
|
||||||
const activeTab = tabs.find(item => item.active);
|
const activeTab = tabs.find(item => item.active);
|
||||||
|
|
||||||
const getCounter = useCallback(
|
const getCounter = useCallback(
|
||||||
(tab: PanelEditorTab) => {
|
(tab: PanelEditorTab) => {
|
||||||
switch (tab.id) {
|
switch (tab.id) {
|
||||||
@@ -65,11 +65,11 @@ export const PanelEditorTabs: React.FC<PanelEditorTabsProps> = ({ panel, dashboa
|
|||||||
<TabContent className={styles.tabContent}>
|
<TabContent className={styles.tabContent}>
|
||||||
{activeTab.id === PanelEditorTabId.Query && <QueriesTab panel={panel} dashboard={dashboard} />}
|
{activeTab.id === PanelEditorTabId.Query && <QueriesTab panel={panel} dashboard={dashboard} />}
|
||||||
{activeTab.id === PanelEditorTabId.Alert && <AlertTab panel={panel} dashboard={dashboard} />}
|
{activeTab.id === PanelEditorTabId.Alert && <AlertTab panel={panel} dashboard={dashboard} />}
|
||||||
{activeTab.id === PanelEditorTabId.Transform && data.state !== LoadingState.NotStarted && (
|
{activeTab.id === PanelEditorTabId.Transform && (
|
||||||
<TransformationsEditor
|
<TransformationsEditor
|
||||||
transformations={panel.transformations || []}
|
transformations={panel.transformations || []}
|
||||||
onChange={onTransformersChange}
|
onChange={onTransformersChange}
|
||||||
dataFrames={data.series}
|
panel={panel}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</TabContent>
|
</TabContent>
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ describe('panelEditor actions', () => {
|
|||||||
...initialState(),
|
...initialState(),
|
||||||
getPanel: () => panel,
|
getPanel: () => panel,
|
||||||
getSourcePanel: () => sourcePanel,
|
getSourcePanel: () => sourcePanel,
|
||||||
querySubscription: { unsubscribe: jest.fn() },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const dispatchedActions = await thunkTester({
|
const dispatchedActions = await thunkTester({
|
||||||
@@ -74,7 +73,6 @@ describe('panelEditor actions', () => {
|
|||||||
...initialState(),
|
...initialState(),
|
||||||
getPanel: () => panel,
|
getPanel: () => panel,
|
||||||
getSourcePanel: () => sourcePanel,
|
getSourcePanel: () => sourcePanel,
|
||||||
querySubscription: { unsubscribe: jest.fn() },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const panelDestroy = (panel.destroy = jest.fn());
|
const panelDestroy = (panel.destroy = jest.fn());
|
||||||
@@ -112,7 +110,6 @@ describe('panelEditor actions', () => {
|
|||||||
shouldDiscardChanges: true,
|
shouldDiscardChanges: true,
|
||||||
getPanel: () => panel,
|
getPanel: () => panel,
|
||||||
getSourcePanel: () => sourcePanel,
|
getSourcePanel: () => sourcePanel,
|
||||||
querySubscription: { unsubscribe: jest.fn() },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const dispatchedActions = await thunkTester({
|
const dispatchedActions = await thunkTester({
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
import { DashboardModel, PanelModel } from '../../../state';
|
import { DashboardModel, PanelModel } from '../../../state';
|
||||||
import { PanelData } from '@grafana/data';
|
|
||||||
import { ThunkResult } from 'app/types';
|
import { ThunkResult } from 'app/types';
|
||||||
import {
|
import {
|
||||||
closeCompleted,
|
closeCompleted,
|
||||||
PANEL_EDITOR_UI_STATE_STORAGE_KEY,
|
PANEL_EDITOR_UI_STATE_STORAGE_KEY,
|
||||||
PanelEditorUIState,
|
PanelEditorUIState,
|
||||||
setEditorPanelData,
|
|
||||||
setPanelEditorUIState,
|
setPanelEditorUIState,
|
||||||
updateEditorInitState,
|
updateEditorInitState,
|
||||||
} from './reducers';
|
} from './reducers';
|
||||||
@@ -16,16 +14,10 @@ export function initPanelEditor(sourcePanel: PanelModel, dashboard: DashboardMod
|
|||||||
return dispatch => {
|
return dispatch => {
|
||||||
const panel = dashboard.initEditPanel(sourcePanel);
|
const panel = dashboard.initEditPanel(sourcePanel);
|
||||||
|
|
||||||
const queryRunner = panel.getQueryRunner();
|
|
||||||
const querySubscription = queryRunner.getData({ withTransforms: false }).subscribe({
|
|
||||||
next: (data: PanelData) => dispatch(setEditorPanelData(data)),
|
|
||||||
});
|
|
||||||
|
|
||||||
dispatch(
|
dispatch(
|
||||||
updateEditorInitState({
|
updateEditorInitState({
|
||||||
panel,
|
panel,
|
||||||
sourcePanel,
|
sourcePanel,
|
||||||
querySubscription,
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -34,7 +26,7 @@ export function initPanelEditor(sourcePanel: PanelModel, dashboard: DashboardMod
|
|||||||
export function panelEditorCleanUp(): ThunkResult<void> {
|
export function panelEditorCleanUp(): ThunkResult<void> {
|
||||||
return (dispatch, getStore) => {
|
return (dispatch, getStore) => {
|
||||||
const dashboard = getStore().dashboard.getModel();
|
const dashboard = getStore().dashboard.getModel();
|
||||||
const { getPanel, getSourcePanel, querySubscription, shouldDiscardChanges } = getStore().panelEditor;
|
const { getPanel, getSourcePanel, shouldDiscardChanges } = getStore().panelEditor;
|
||||||
|
|
||||||
if (!shouldDiscardChanges) {
|
if (!shouldDiscardChanges) {
|
||||||
const panel = getPanel();
|
const panel = getPanel();
|
||||||
@@ -66,10 +58,6 @@ export function panelEditorCleanUp(): ThunkResult<void> {
|
|||||||
dashboard.exitPanelEditor();
|
dashboard.exitPanelEditor();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (querySubscription) {
|
|
||||||
querySubscription.unsubscribe();
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatch(cleanUpEditPanel());
|
dispatch(cleanUpEditPanel());
|
||||||
dispatch(closeCompleted());
|
dispatch(closeCompleted());
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { Unsubscribable } from 'rxjs';
|
|
||||||
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
|
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
|
||||||
import { PanelModel } from '../../../state/PanelModel';
|
import { PanelModel } from '../../../state/PanelModel';
|
||||||
import { DefaultTimeRange, LoadingState, PanelData } from '@grafana/data';
|
import { DefaultTimeRange, LoadingState, PanelData } from '@grafana/data';
|
||||||
@@ -31,7 +30,6 @@ export interface PanelEditorState {
|
|||||||
getSourcePanel: () => PanelModel;
|
getSourcePanel: () => PanelModel;
|
||||||
getPanel: () => PanelModel;
|
getPanel: () => PanelModel;
|
||||||
getData: () => PanelData;
|
getData: () => PanelData;
|
||||||
querySubscription?: Unsubscribable;
|
|
||||||
initDone: boolean;
|
initDone: boolean;
|
||||||
shouldDiscardChanges: boolean;
|
shouldDiscardChanges: boolean;
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
@@ -60,7 +58,6 @@ export const initialState = (): PanelEditorState => {
|
|||||||
interface InitEditorPayload {
|
interface InitEditorPayload {
|
||||||
panel: PanelModel;
|
panel: PanelModel;
|
||||||
sourcePanel: PanelModel;
|
sourcePanel: PanelModel;
|
||||||
querySubscription: Unsubscribable;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const pluginsSlice = createSlice({
|
const pluginsSlice = createSlice({
|
||||||
@@ -70,7 +67,6 @@ const pluginsSlice = createSlice({
|
|||||||
updateEditorInitState: (state, action: PayloadAction<InitEditorPayload>) => {
|
updateEditorInitState: (state, action: PayloadAction<InitEditorPayload>) => {
|
||||||
state.getPanel = () => action.payload.panel;
|
state.getPanel = () => action.payload.panel;
|
||||||
state.getSourcePanel = () => action.payload.sourcePanel;
|
state.getSourcePanel = () => action.payload.sourcePanel;
|
||||||
state.querySubscription = action.payload.querySubscription;
|
|
||||||
state.initDone = true;
|
state.initDone = true;
|
||||||
state.isOpen = true;
|
state.isOpen = true;
|
||||||
state.shouldDiscardChanges = false;
|
state.shouldDiscardChanges = false;
|
||||||
|
|||||||
@@ -2,15 +2,16 @@ import { PanelData } from '@grafana/data';
|
|||||||
import { useEffect, useRef, useState } from 'react';
|
import { useEffect, useRef, useState } from 'react';
|
||||||
import { PanelModel } from '../../state';
|
import { PanelModel } from '../../state';
|
||||||
import { Unsubscribable } from 'rxjs';
|
import { Unsubscribable } from 'rxjs';
|
||||||
|
import { GetDataOptions } from '../../state/PanelQueryRunner';
|
||||||
|
|
||||||
export const usePanelLatestData = (panel: PanelModel): [PanelData | null, boolean] => {
|
export const usePanelLatestData = (panel: PanelModel, options: GetDataOptions): [PanelData | null, boolean] => {
|
||||||
const querySubscription = useRef<Unsubscribable>(null);
|
const querySubscription = useRef<Unsubscribable>(null);
|
||||||
const [latestData, setLatestData] = useState<PanelData>(null);
|
const [latestData, setLatestData] = useState<PanelData>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
querySubscription.current = panel
|
querySubscription.current = panel
|
||||||
.getQueryRunner()
|
.getQueryRunner()
|
||||||
.getData()
|
.getData(options)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: data => setLatestData(data),
|
next: data => setLatestData(data),
|
||||||
});
|
});
|
||||||
|
|||||||
+31
-5
@@ -10,26 +10,50 @@ import {
|
|||||||
VerticalGroup,
|
VerticalGroup,
|
||||||
} from '@grafana/ui';
|
} from '@grafana/ui';
|
||||||
import {
|
import {
|
||||||
DataFrame,
|
|
||||||
DataTransformerConfig,
|
DataTransformerConfig,
|
||||||
FeatureState,
|
FeatureState,
|
||||||
GrafanaTheme,
|
GrafanaTheme,
|
||||||
SelectableValue,
|
SelectableValue,
|
||||||
standardTransformersRegistry,
|
standardTransformersRegistry,
|
||||||
transformDataFrame,
|
transformDataFrame,
|
||||||
|
DataFrame,
|
||||||
|
PanelData,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
import { TransformationOperationRow } from './TransformationOperationRow';
|
import { TransformationOperationRow } from './TransformationOperationRow';
|
||||||
import { Card, CardProps } from '../../../../core/components/Card/Card';
|
import { Card, CardProps } from '../../../../core/components/Card/Card';
|
||||||
import { css } from 'emotion';
|
import { css } from 'emotion';
|
||||||
import { selectors } from '@grafana/e2e-selectors';
|
import { selectors } from '@grafana/e2e-selectors';
|
||||||
|
import { Unsubscribable } from 'rxjs';
|
||||||
|
import { PanelModel } from '../../state';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
panel: PanelModel;
|
||||||
onChange: (transformations: DataTransformerConfig[]) => void;
|
onChange: (transformations: DataTransformerConfig[]) => void;
|
||||||
transformations: DataTransformerConfig[];
|
transformations: DataTransformerConfig[];
|
||||||
dataFrames: DataFrame[];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TransformationsEditor extends React.PureComponent<Props> {
|
interface State {
|
||||||
|
data?: DataFrame[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export class TransformationsEditor extends React.PureComponent<Props, State> {
|
||||||
|
subscription?: Unsubscribable;
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.subscription = this.props.panel
|
||||||
|
.getQueryRunner()
|
||||||
|
.getData({ withTransforms: false, withFieldConfig: false })
|
||||||
|
.subscribe({
|
||||||
|
next: (panelData: PanelData) => this.setState({ data: panelData.series }),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
if (this.subscription) {
|
||||||
|
this.subscription.unsubscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onTransformationAdd = (selectable: SelectableValue<string>) => {
|
onTransformationAdd = (selectable: SelectableValue<string>) => {
|
||||||
const { transformations, onChange } = this.props;
|
const { transformations, onChange } = this.props;
|
||||||
onChange([
|
onChange([
|
||||||
@@ -84,8 +108,10 @@ export class TransformationsEditor extends React.PureComponent<Props> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
renderTransformationEditors = () => {
|
renderTransformationEditors = () => {
|
||||||
const { transformations, dataFrames } = this.props;
|
const { transformations } = this.props;
|
||||||
const preTransformData = dataFrames;
|
const { data } = this.state;
|
||||||
|
|
||||||
|
const preTransformData = data ?? [];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ export class PanelChrome extends PureComponent<Props, State> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const { panel, dashboard, isEditing } = this.props;
|
const { panel, dashboard } = this.props;
|
||||||
|
|
||||||
panel.events.on(PanelEvents.refresh, this.onRefresh);
|
panel.events.on(PanelEvents.refresh, this.onRefresh);
|
||||||
panel.events.on(PanelEvents.render, this.onRender);
|
panel.events.on(PanelEvents.render, this.onRender);
|
||||||
@@ -87,29 +87,19 @@ export class PanelChrome extends PureComponent<Props, State> {
|
|||||||
},
|
},
|
||||||
isFirstLoad: false,
|
isFirstLoad: false,
|
||||||
});
|
});
|
||||||
} else {
|
return;
|
||||||
if (isEditing) {
|
|
||||||
this.querySubscription = panel
|
|
||||||
.getQueryRunner()
|
|
||||||
.getData()
|
|
||||||
.subscribe({
|
|
||||||
next: data => this.onDataUpdate(data),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.wantsQueryExecution) {
|
|
||||||
this.setState({ isFirstLoad: false });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.querySubscription) {
|
if (!this.wantsQueryExecution) {
|
||||||
this.querySubscription = panel
|
this.setState({ isFirstLoad: false });
|
||||||
.getQueryRunner()
|
|
||||||
.getData()
|
|
||||||
.subscribe({
|
|
||||||
next: data => this.onDataUpdate(data),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.querySubscription = panel
|
||||||
|
.getQueryRunner()
|
||||||
|
.getData({ withTransforms: true, withFieldConfig: true })
|
||||||
|
.subscribe({
|
||||||
|
next: data => this.onDataUpdate(data),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
|
|||||||
@@ -78,7 +78,9 @@ export class PanelChromeAngularUnconnected extends PureComponent<Props, State> {
|
|||||||
|
|
||||||
// subscribe to data events
|
// subscribe to data events
|
||||||
const queryRunner = panel.getQueryRunner();
|
const queryRunner = panel.getQueryRunner();
|
||||||
this.querySubscription = queryRunner.getData({ withTransforms: false }).subscribe({
|
|
||||||
|
// we are not displaying any of this data so no need for transforms or field config
|
||||||
|
this.querySubscription = queryRunner.getData({ withTransforms: false, withFieldConfig: false }).subscribe({
|
||||||
next: (data: PanelData) => this.onPanelDataUpdate(data),
|
next: (data: PanelData) => this.onPanelDataUpdate(data),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ export class QueriesTab extends PureComponent<Props, State> {
|
|||||||
const { panel } = this.props;
|
const { panel } = this.props;
|
||||||
const queryRunner = panel.getQueryRunner();
|
const queryRunner = panel.getQueryRunner();
|
||||||
|
|
||||||
this.querySubscription = queryRunner.getData({ withTransforms: false }).subscribe({
|
this.querySubscription = queryRunner.getData({ withTransforms: false, withFieldConfig: false }).subscribe({
|
||||||
next: (data: PanelData) => this.onPanelDataUpdate(data),
|
next: (data: PanelData) => this.onPanelDataUpdate(data),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ function describeQueryRunnerScenario(description: string, scenarioFn: ScenarioFn
|
|||||||
};
|
};
|
||||||
|
|
||||||
ctx.runner = new PanelQueryRunner(panelConfig || defaultPanelConfig);
|
ctx.runner = new PanelQueryRunner(panelConfig || defaultPanelConfig);
|
||||||
ctx.runner.getData().subscribe({
|
ctx.runner.getData({ withTransforms: true, withFieldConfig: true }).subscribe({
|
||||||
next: (data: PanelData) => {
|
next: (data: PanelData) => {
|
||||||
ctx.res = data;
|
ctx.res = data;
|
||||||
ctx.events?.push(data);
|
ctx.events?.push(data);
|
||||||
@@ -201,7 +201,7 @@ describe('PanelQueryRunner', () => {
|
|||||||
it('should apply when field override options are set', async () => {
|
it('should apply when field override options are set', async () => {
|
||||||
const spy = jest.spyOn(grafanaData, 'applyFieldOverrides');
|
const spy = jest.spyOn(grafanaData, 'applyFieldOverrides');
|
||||||
|
|
||||||
ctx.runner.getData().subscribe({
|
ctx.runner.getData({ withTransforms: true, withFieldConfig: true }).subscribe({
|
||||||
next: (data: PanelData) => {
|
next: (data: PanelData) => {
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
@@ -232,7 +232,7 @@ describe('PanelQueryRunner', () => {
|
|||||||
const spy = jest.spyOn(grafanaData, 'transformDataFrame');
|
const spy = jest.spyOn(grafanaData, 'transformDataFrame');
|
||||||
spy.mockClear();
|
spy.mockClear();
|
||||||
|
|
||||||
ctx.runner.getData().subscribe({
|
ctx.runner.getData({ withTransforms: true, withFieldConfig: true }).subscribe({
|
||||||
next: (data: PanelData) => {
|
next: (data: PanelData) => {
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
@@ -254,7 +254,7 @@ describe('PanelQueryRunner', () => {
|
|||||||
it('should not apply transformations when transform option is false', async () => {
|
it('should not apply transformations when transform option is false', async () => {
|
||||||
const spy = jest.spyOn(grafanaData, 'transformDataFrame');
|
const spy = jest.spyOn(grafanaData, 'transformDataFrame');
|
||||||
spy.mockClear();
|
spy.mockClear();
|
||||||
ctx.runner.getData({ withTransforms: false }).subscribe({
|
ctx.runner.getData({ withTransforms: false, withFieldConfig: true }).subscribe({
|
||||||
next: (data: PanelData) => {
|
next: (data: PanelData) => {
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
@@ -266,7 +266,7 @@ describe('PanelQueryRunner', () => {
|
|||||||
it('should not apply field config when applyFieldConfig option is false', async () => {
|
it('should not apply field config when applyFieldConfig option is false', async () => {
|
||||||
const spy = jest.spyOn(grafanaData, 'applyFieldOverrides');
|
const spy = jest.spyOn(grafanaData, 'applyFieldOverrides');
|
||||||
spy.mockClear();
|
spy.mockClear();
|
||||||
ctx.runner.getData({ withFieldConfig: false }).subscribe({
|
ctx.runner.getData({ withFieldConfig: false, withTransforms: true }).subscribe({
|
||||||
next: (data: PanelData) => {
|
next: (data: PanelData) => {
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -52,13 +52,9 @@ function getNextRequestId() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface GetDataOptions {
|
export interface GetDataOptions {
|
||||||
withTransforms?: boolean;
|
withTransforms: boolean;
|
||||||
withFieldConfig?: boolean;
|
withFieldConfig: boolean;
|
||||||
}
|
}
|
||||||
const DEFAULT_GET_DATA_OPTIONS: GetDataOptions = {
|
|
||||||
withTransforms: true,
|
|
||||||
withFieldConfig: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
export class PanelQueryRunner {
|
export class PanelQueryRunner {
|
||||||
private subject?: ReplaySubject<PanelData>;
|
private subject?: ReplaySubject<PanelData>;
|
||||||
@@ -75,7 +71,7 @@ export class PanelQueryRunner {
|
|||||||
/**
|
/**
|
||||||
* Returns an observable that subscribes to the shared multi-cast subject (that reply last result).
|
* Returns an observable that subscribes to the shared multi-cast subject (that reply last result).
|
||||||
*/
|
*/
|
||||||
getData(options: GetDataOptions = DEFAULT_GET_DATA_OPTIONS): Observable<PanelData> {
|
getData(options: GetDataOptions): Observable<PanelData> {
|
||||||
const { withFieldConfig, withTransforms } = options;
|
const { withFieldConfig, withTransforms } = options;
|
||||||
|
|
||||||
return this.subject.pipe(
|
return this.subject.pipe(
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import {
|
|||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
import { Unsubscribable } from 'rxjs';
|
import { Unsubscribable } from 'rxjs';
|
||||||
import { PanelModel } from 'app/features/dashboard/state';
|
import { PanelModel } from 'app/features/dashboard/state';
|
||||||
|
import { PanelQueryRunner } from '../dashboard/state/PanelQueryRunner';
|
||||||
|
|
||||||
class MetricsPanelCtrl extends PanelCtrl {
|
class MetricsPanelCtrl extends PanelCtrl {
|
||||||
scope: any;
|
scope: any;
|
||||||
@@ -51,8 +52,10 @@ class MetricsPanelCtrl extends PanelCtrl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private onMetricsPanelMounted() {
|
private onMetricsPanelMounted() {
|
||||||
const queryRunner = this.panel.getQueryRunner();
|
const queryRunner = this.panel.getQueryRunner() as PanelQueryRunner;
|
||||||
this.querySubscription = queryRunner.getData().subscribe(this.panelDataObserver);
|
this.querySubscription = queryRunner
|
||||||
|
.getData({ withTransforms: true, withFieldConfig: true })
|
||||||
|
.subscribe(this.panelDataObserver);
|
||||||
}
|
}
|
||||||
|
|
||||||
private onPanelTearDown() {
|
private onPanelTearDown() {
|
||||||
|
|||||||
Reference in New Issue
Block a user