Commit 923faf78 by Torkel Ödegaard Committed by GitHub

PanelEditor: Overrides name matcher still show all original field names even…

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
parent 3a469f6c
......@@ -35,7 +35,7 @@ export const OptionsPaneContent: React.FC<Props> = ({
const styles = getStyles(theme);
const [activeTab, setActiveTab] = useState('options');
const [isSearching, setSearchMode] = useState(false);
const [currentData, hasSeries] = usePanelLatestData(panel);
const [currentData, hasSeries] = usePanelLatestData(panel, { withTransforms: true, withFieldConfig: false });
const renderFieldOptions = useCallback(
(plugin: PanelPlugin) => {
......
......@@ -51,11 +51,13 @@ export const OverrideEditor: React.FC<OverrideEditorProps> = ({
const theme = useTheme();
const matcherUi = fieldMatchersUI.get(override.matcher.id);
const styles = getStyles(theme);
const matcherLabel = (
<Label category={['Matcher']} description={matcherUi.description}>
{matcherUi.name}
</Label>
);
const onMatcherConfigChange = useCallback(
(matcherConfig: any) => {
override.matcher.options = matcherConfig;
......
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 { css, cx } from 'emotion';
import config from 'app/core/config';
......@@ -42,7 +42,6 @@ interface ConnectedProps {
location: LocationState;
plugin?: PanelPlugin;
panel: PanelModel;
data: PanelData;
initDone: boolean;
tabs: PanelEditorTab[];
uiState: PanelEditorUIState;
......@@ -183,7 +182,7 @@ export class PanelEditorUnconnected extends PureComponent<Props> {
);
};
renderHorizontalSplit(styles: EditorStyles) {
const { dashboard, panel, tabs, data, uiState } = this.props;
const { dashboard, panel, tabs, uiState } = this.props;
return tabs.length > 0 ? (
<SplitPane
split="horizontal"
......@@ -198,7 +197,7 @@ export class PanelEditorUnconnected extends PureComponent<Props> {
>
{this.renderPanel(styles)}
<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>
</SplitPane>
) : (
......@@ -350,7 +349,6 @@ const mapStateToProps: MapStateToProps<ConnectedProps, OwnProps, StoreState> = (
location: state.location,
plugin: plugin,
panel,
data: state.panelEditor.getData(),
initDone: state.panelEditor.initDone,
tabs: getPanelEditorTabs(state.location, plugin),
uiState: state.panelEditor.ui,
......
......@@ -2,7 +2,7 @@ import React, { useCallback } from 'react';
import { config } from 'app/core/config';
import { css } from 'emotion';
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 { DashboardModel } from '../../state';
import { QueriesTab } from '../../panel_editor/QueriesTab';
......@@ -15,12 +15,12 @@ interface PanelEditorTabsProps {
dashboard: DashboardModel;
tabs: PanelEditorTab[];
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 activeTab = tabs.find(item => item.active);
const getCounter = useCallback(
(tab: PanelEditorTab) => {
switch (tab.id) {
......@@ -65,11 +65,11 @@ export const PanelEditorTabs: React.FC<PanelEditorTabsProps> = ({ panel, dashboa
<TabContent className={styles.tabContent}>
{activeTab.id === PanelEditorTabId.Query && <QueriesTab 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
transformations={panel.transformations || []}
onChange={onTransformersChange}
dataFrames={data.series}
panel={panel}
/>
)}
</TabContent>
......
......@@ -40,7 +40,6 @@ describe('panelEditor actions', () => {
...initialState(),
getPanel: () => panel,
getSourcePanel: () => sourcePanel,
querySubscription: { unsubscribe: jest.fn() },
};
const dispatchedActions = await thunkTester({
......@@ -74,7 +73,6 @@ describe('panelEditor actions', () => {
...initialState(),
getPanel: () => panel,
getSourcePanel: () => sourcePanel,
querySubscription: { unsubscribe: jest.fn() },
};
const panelDestroy = (panel.destroy = jest.fn());
......@@ -112,7 +110,6 @@ describe('panelEditor actions', () => {
shouldDiscardChanges: true,
getPanel: () => panel,
getSourcePanel: () => sourcePanel,
querySubscription: { unsubscribe: jest.fn() },
};
const dispatchedActions = await thunkTester({
......
import { DashboardModel, PanelModel } from '../../../state';
import { PanelData } from '@grafana/data';
import { ThunkResult } from 'app/types';
import {
closeCompleted,
PANEL_EDITOR_UI_STATE_STORAGE_KEY,
PanelEditorUIState,
setEditorPanelData,
setPanelEditorUIState,
updateEditorInitState,
} from './reducers';
......@@ -16,16 +14,10 @@ export function initPanelEditor(sourcePanel: PanelModel, dashboard: DashboardMod
return dispatch => {
const panel = dashboard.initEditPanel(sourcePanel);
const queryRunner = panel.getQueryRunner();
const querySubscription = queryRunner.getData({ withTransforms: false }).subscribe({
next: (data: PanelData) => dispatch(setEditorPanelData(data)),
});
dispatch(
updateEditorInitState({
panel,
sourcePanel,
querySubscription,
})
);
};
......@@ -34,7 +26,7 @@ export function initPanelEditor(sourcePanel: PanelModel, dashboard: DashboardMod
export function panelEditorCleanUp(): ThunkResult<void> {
return (dispatch, getStore) => {
const dashboard = getStore().dashboard.getModel();
const { getPanel, getSourcePanel, querySubscription, shouldDiscardChanges } = getStore().panelEditor;
const { getPanel, getSourcePanel, shouldDiscardChanges } = getStore().panelEditor;
if (!shouldDiscardChanges) {
const panel = getPanel();
......@@ -66,10 +58,6 @@ export function panelEditorCleanUp(): ThunkResult<void> {
dashboard.exitPanelEditor();
}
if (querySubscription) {
querySubscription.unsubscribe();
}
dispatch(cleanUpEditPanel());
dispatch(closeCompleted());
};
......
import { Unsubscribable } from 'rxjs';
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import { PanelModel } from '../../../state/PanelModel';
import { DefaultTimeRange, LoadingState, PanelData } from '@grafana/data';
......@@ -31,7 +30,6 @@ export interface PanelEditorState {
getSourcePanel: () => PanelModel;
getPanel: () => PanelModel;
getData: () => PanelData;
querySubscription?: Unsubscribable;
initDone: boolean;
shouldDiscardChanges: boolean;
isOpen: boolean;
......@@ -60,7 +58,6 @@ export const initialState = (): PanelEditorState => {
interface InitEditorPayload {
panel: PanelModel;
sourcePanel: PanelModel;
querySubscription: Unsubscribable;
}
const pluginsSlice = createSlice({
......@@ -70,7 +67,6 @@ const pluginsSlice = createSlice({
updateEditorInitState: (state, action: PayloadAction<InitEditorPayload>) => {
state.getPanel = () => action.payload.panel;
state.getSourcePanel = () => action.payload.sourcePanel;
state.querySubscription = action.payload.querySubscription;
state.initDone = true;
state.isOpen = true;
state.shouldDiscardChanges = false;
......
......@@ -2,15 +2,16 @@ import { PanelData } from '@grafana/data';
import { useEffect, useRef, useState } from 'react';
import { PanelModel } from '../../state';
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 [latestData, setLatestData] = useState<PanelData>(null);
useEffect(() => {
querySubscription.current = panel
.getQueryRunner()
.getData()
.getData(options)
.subscribe({
next: data => setLatestData(data),
});
......
......@@ -10,26 +10,50 @@ import {
VerticalGroup,
} from '@grafana/ui';
import {
DataFrame,
DataTransformerConfig,
FeatureState,
GrafanaTheme,
SelectableValue,
standardTransformersRegistry,
transformDataFrame,
DataFrame,
PanelData,
} from '@grafana/data';
import { TransformationOperationRow } from './TransformationOperationRow';
import { Card, CardProps } from '../../../../core/components/Card/Card';
import { css } from 'emotion';
import { selectors } from '@grafana/e2e-selectors';
import { Unsubscribable } from 'rxjs';
import { PanelModel } from '../../state';
interface Props {
panel: PanelModel;
onChange: (transformations: DataTransformerConfig[]) => void;
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>) => {
const { transformations, onChange } = this.props;
onChange([
......@@ -84,8 +108,10 @@ export class TransformationsEditor extends React.PureComponent<Props> {
};
renderTransformationEditors = () => {
const { transformations, dataFrames } = this.props;
const preTransformData = dataFrames;
const { transformations } = this.props;
const { data } = this.state;
const preTransformData = data ?? [];
return (
<>
......
......@@ -70,7 +70,7 @@ export class PanelChrome extends PureComponent<Props, State> {
}
componentDidMount() {
const { panel, dashboard, isEditing } = this.props;
const { panel, dashboard } = this.props;
panel.events.on(PanelEvents.refresh, this.onRefresh);
panel.events.on(PanelEvents.render, this.onRender);
......@@ -87,29 +87,19 @@ export class PanelChrome extends PureComponent<Props, State> {
},
isFirstLoad: false,
});
} else {
if (isEditing) {
this.querySubscription = panel
.getQueryRunner()
.getData()
.subscribe({
next: data => this.onDataUpdate(data),
});
}
if (!this.wantsQueryExecution) {
this.setState({ isFirstLoad: false });
}
return;
}
if (!this.querySubscription) {
this.querySubscription = panel
.getQueryRunner()
.getData()
.subscribe({
next: data => this.onDataUpdate(data),
});
if (!this.wantsQueryExecution) {
this.setState({ isFirstLoad: false });
}
this.querySubscription = panel
.getQueryRunner()
.getData({ withTransforms: true, withFieldConfig: true })
.subscribe({
next: data => this.onDataUpdate(data),
});
}
componentWillUnmount() {
......
......@@ -78,7 +78,9 @@ export class PanelChromeAngularUnconnected extends PureComponent<Props, State> {
// subscribe to data events
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),
});
}
......
......@@ -71,7 +71,7 @@ export class QueriesTab extends PureComponent<Props, State> {
const { panel } = this.props;
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),
});
......
......@@ -103,7 +103,7 @@ function describeQueryRunnerScenario(description: string, scenarioFn: ScenarioFn
};
ctx.runner = new PanelQueryRunner(panelConfig || defaultPanelConfig);
ctx.runner.getData().subscribe({
ctx.runner.getData({ withTransforms: true, withFieldConfig: true }).subscribe({
next: (data: PanelData) => {
ctx.res = data;
ctx.events?.push(data);
......@@ -201,7 +201,7 @@ describe('PanelQueryRunner', () => {
it('should apply when field override options are set', async () => {
const spy = jest.spyOn(grafanaData, 'applyFieldOverrides');
ctx.runner.getData().subscribe({
ctx.runner.getData({ withTransforms: true, withFieldConfig: true }).subscribe({
next: (data: PanelData) => {
return data;
},
......@@ -232,7 +232,7 @@ describe('PanelQueryRunner', () => {
const spy = jest.spyOn(grafanaData, 'transformDataFrame');
spy.mockClear();
ctx.runner.getData().subscribe({
ctx.runner.getData({ withTransforms: true, withFieldConfig: true }).subscribe({
next: (data: PanelData) => {
return data;
},
......@@ -254,7 +254,7 @@ describe('PanelQueryRunner', () => {
it('should not apply transformations when transform option is false', async () => {
const spy = jest.spyOn(grafanaData, 'transformDataFrame');
spy.mockClear();
ctx.runner.getData({ withTransforms: false }).subscribe({
ctx.runner.getData({ withTransforms: false, withFieldConfig: true }).subscribe({
next: (data: PanelData) => {
return data;
},
......@@ -266,7 +266,7 @@ describe('PanelQueryRunner', () => {
it('should not apply field config when applyFieldConfig option is false', async () => {
const spy = jest.spyOn(grafanaData, 'applyFieldOverrides');
spy.mockClear();
ctx.runner.getData({ withFieldConfig: false }).subscribe({
ctx.runner.getData({ withFieldConfig: false, withTransforms: true }).subscribe({
next: (data: PanelData) => {
return data;
},
......
......@@ -52,13 +52,9 @@ function getNextRequestId() {
}
export interface GetDataOptions {
withTransforms?: boolean;
withFieldConfig?: boolean;
withTransforms: boolean;
withFieldConfig: boolean;
}
const DEFAULT_GET_DATA_OPTIONS: GetDataOptions = {
withTransforms: true,
withFieldConfig: true,
};
export class PanelQueryRunner {
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).
*/
getData(options: GetDataOptions = DEFAULT_GET_DATA_OPTIONS): Observable<PanelData> {
getData(options: GetDataOptions): Observable<PanelData> {
const { withFieldConfig, withTransforms } = options;
return this.subject.pipe(
......
......@@ -16,6 +16,7 @@ import {
} from '@grafana/data';
import { Unsubscribable } from 'rxjs';
import { PanelModel } from 'app/features/dashboard/state';
import { PanelQueryRunner } from '../dashboard/state/PanelQueryRunner';
class MetricsPanelCtrl extends PanelCtrl {
scope: any;
......@@ -51,8 +52,10 @@ class MetricsPanelCtrl extends PanelCtrl {
}
private onMetricsPanelMounted() {
const queryRunner = this.panel.getQueryRunner();
this.querySubscription = queryRunner.getData().subscribe(this.panelDataObserver);
const queryRunner = this.panel.getQueryRunner() as PanelQueryRunner;
this.querySubscription = queryRunner
.getData({ withTransforms: true, withFieldConfig: true })
.subscribe(this.panelDataObserver);
}
private onPanelTearDown() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment