Commit eae11f53 by Dominik Prokop Committed by GitHub

Transformations: Make sidebar subscribe to panel's query runner (#23785)

* Make panel edit sidebar options use lates data from panel query runner

* Update select's z-index

* Review
parent 45dfa204
import React, { useCallback, useState, CSSProperties } from 'react'; import React, { useCallback, useState, CSSProperties } from 'react';
import Transition from 'react-transition-group/Transition'; import Transition from 'react-transition-group/Transition';
import { FieldConfigSource, GrafanaTheme, PanelData, PanelPlugin, SelectableValue } from '@grafana/data'; import { FieldConfigSource, GrafanaTheme, PanelPlugin, SelectableValue } from '@grafana/data';
import { DashboardModel, PanelModel } from '../../state'; import { DashboardModel, PanelModel } from '../../state';
import { CustomScrollbar, stylesFactory, Tab, TabContent, TabsBar, Select, useTheme, Icon, Input } from '@grafana/ui'; import { CustomScrollbar, stylesFactory, Tab, TabContent, TabsBar, Select, useTheme, Icon, Input } from '@grafana/ui';
import { DefaultFieldConfigEditor, OverrideFieldConfigEditor } from './FieldConfigEditor'; import { DefaultFieldConfigEditor, OverrideFieldConfigEditor } from './FieldConfigEditor';
import { css } from 'emotion'; import { css } from 'emotion';
import { PanelOptionsTab } from './PanelOptionsTab'; import { PanelOptionsTab } from './PanelOptionsTab';
import { DashNavButton } from 'app/features/dashboard/components/DashNav/DashNavButton'; import { DashNavButton } from 'app/features/dashboard/components/DashNav/DashNavButton';
import { usePanelLatestData } from './usePanelLatestData';
interface Props { interface Props {
plugin: PanelPlugin; plugin: PanelPlugin;
panel: PanelModel; panel: PanelModel;
data: PanelData;
width: number; width: number;
dashboard: DashboardModel; dashboard: DashboardModel;
onClose: () => void; onClose: () => void;
...@@ -23,7 +23,6 @@ interface Props { ...@@ -23,7 +23,6 @@ interface Props {
export const OptionsPaneContent: React.FC<Props> = ({ export const OptionsPaneContent: React.FC<Props> = ({
plugin, plugin,
panel, panel,
data,
width, width,
onFieldConfigsChange, onFieldConfigsChange,
onPanelOptionsChanged, onPanelOptionsChanged,
...@@ -35,12 +34,13 @@ export const OptionsPaneContent: React.FC<Props> = ({ ...@@ -35,12 +34,13 @@ 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 renderFieldOptions = useCallback( const renderFieldOptions = useCallback(
(plugin: PanelPlugin) => { (plugin: PanelPlugin) => {
const fieldConfig = panel.getFieldConfig(); const fieldConfig = panel.getFieldConfig();
if (!fieldConfig) { if (!fieldConfig || !hasSeries) {
return null; return null;
} }
...@@ -49,18 +49,18 @@ export const OptionsPaneContent: React.FC<Props> = ({ ...@@ -49,18 +49,18 @@ export const OptionsPaneContent: React.FC<Props> = ({
config={fieldConfig} config={fieldConfig}
plugin={plugin} plugin={plugin}
onChange={onFieldConfigsChange} onChange={onFieldConfigsChange}
data={data.series} data={currentData.series}
/> />
); );
}, },
[data, plugin, panel, onFieldConfigsChange] [currentData, plugin, panel, onFieldConfigsChange]
); );
const renderFieldOverrideOptions = useCallback( const renderFieldOverrideOptions = useCallback(
(plugin: PanelPlugin) => { (plugin: PanelPlugin) => {
const fieldConfig = panel.getFieldConfig(); const fieldConfig = panel.getFieldConfig();
if (!fieldConfig) { if (!fieldConfig || !hasSeries) {
return null; return null;
} }
...@@ -69,11 +69,11 @@ export const OptionsPaneContent: React.FC<Props> = ({ ...@@ -69,11 +69,11 @@ export const OptionsPaneContent: React.FC<Props> = ({
config={fieldConfig} config={fieldConfig}
plugin={plugin} plugin={plugin}
onChange={onFieldConfigsChange} onChange={onFieldConfigsChange}
data={data.series} data={currentData.series}
/> />
); );
}, },
[data, plugin, panel, onFieldConfigsChange] [currentData, plugin, panel, onFieldConfigsChange]
); );
// When the panel has no query only show the main tab // When the panel has no query only show the main tab
...@@ -103,7 +103,7 @@ export const OptionsPaneContent: React.FC<Props> = ({ ...@@ -103,7 +103,7 @@ export const OptionsPaneContent: React.FC<Props> = ({
panel={panel} panel={panel}
plugin={plugin} plugin={plugin}
dashboard={dashboard} dashboard={dashboard}
data={data} data={currentData}
onPanelConfigChange={onPanelConfigChange} onPanelConfigChange={onPanelConfigChange}
onFieldConfigsChange={onFieldConfigsChange} onFieldConfigsChange={onFieldConfigsChange}
onPanelOptionsChanged={onPanelOptionsChanged} onPanelOptionsChanged={onPanelOptionsChanged}
......
...@@ -275,7 +275,7 @@ export class PanelEditorUnconnected extends PureComponent<Props> { ...@@ -275,7 +275,7 @@ export class PanelEditorUnconnected extends PureComponent<Props> {
} }
renderOptionsPane() { renderOptionsPane() {
const { plugin, dashboard, data, panel, uiState } = this.props; const { plugin, dashboard, panel, uiState } = this.props;
if (!plugin) { if (!plugin) {
return <div />; return <div />;
...@@ -285,7 +285,6 @@ export class PanelEditorUnconnected extends PureComponent<Props> { ...@@ -285,7 +285,6 @@ export class PanelEditorUnconnected extends PureComponent<Props> {
<OptionsPaneContent <OptionsPaneContent
plugin={plugin} plugin={plugin}
dashboard={dashboard} dashboard={dashboard}
data={data}
panel={panel} panel={panel}
width={uiState.rightPaneSize as number} width={uiState.rightPaneSize as number}
onClose={this.onTogglePanelOptions} onClose={this.onTogglePanelOptions}
......
import { PanelData } from '@grafana/data';
import { useEffect, useRef, useState } from 'react';
import { PanelModel } from '../../state';
import { Unsubscribable } from 'rxjs';
export const usePanelLatestData = (panel: PanelModel): [PanelData | null, boolean] => {
const querySubscription = useRef<Unsubscribable>(null);
const [latestData, setLatestData] = useState<PanelData>(null);
useEffect(() => {
querySubscription.current = panel
.getQueryRunner()
.getData()
.subscribe({
next: data => setLatestData(data),
});
return () => {
if (querySubscription.current) {
console.log('unsubscribing');
querySubscription.current.unsubscribe();
}
};
}, [panel]);
return [
latestData,
// TODO: make this more clever, use PanelData.state
!!(latestData && latestData.series),
];
};
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