mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
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
This commit is contained in:
parent
45dfa20467
commit
eae11f53f3
@ -1,17 +1,17 @@
|
|||||||
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 {
|
|||||||
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> = ({
|
|||||||
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> = ({
|
|||||||
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> = ({
|
|||||||
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> = ({
|
|||||||
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> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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> {
|
|||||||
<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}
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
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),
|
||||||
|
];
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user