Merge pull request #14898 from grafana/hughag/template-variable-support-for-react-panels
Template variable support for react panels
This commit is contained in:
@@ -1,6 +1,8 @@
|
|||||||
import { TimeSeries, LoadingState } from './series';
|
import { TimeSeries, LoadingState } from './series';
|
||||||
import { TimeRange } from './time';
|
import { TimeRange } from './time';
|
||||||
|
|
||||||
|
export type InterpolateFunction = (value: string, format?: string | Function) => string;
|
||||||
|
|
||||||
export interface PanelProps<T = any> {
|
export interface PanelProps<T = any> {
|
||||||
timeSeries: TimeSeries[];
|
timeSeries: TimeSeries[];
|
||||||
timeRange: TimeRange;
|
timeRange: TimeRange;
|
||||||
@@ -9,6 +11,7 @@ export interface PanelProps<T = any> {
|
|||||||
renderCounter: number;
|
renderCounter: number;
|
||||||
width: number;
|
width: number;
|
||||||
height: number;
|
height: number;
|
||||||
|
onInterpolate: InterpolateFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PanelOptionsProps<T = any> {
|
export interface PanelOptionsProps<T = any> {
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import { PanelPlugin } from 'app/types';
|
|||||||
import { TimeRange } from '@grafana/ui';
|
import { TimeRange } from '@grafana/ui';
|
||||||
|
|
||||||
import variables from 'sass/_variables.scss';
|
import variables from 'sass/_variables.scss';
|
||||||
|
import templateSrv from 'app/features/templating/template_srv';
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
panel: PanelModel;
|
panel: PanelModel;
|
||||||
@@ -78,6 +79,10 @@ export class PanelChrome extends PureComponent<Props, State> {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
onInterpolate = (value: string, format?: string) => {
|
||||||
|
return templateSrv.replace(value, this.props.panel.scopedVars, format);
|
||||||
|
};
|
||||||
|
|
||||||
get isVisible() {
|
get isVisible() {
|
||||||
return !this.props.dashboard.otherPanelInFullscreen(this.props.panel);
|
return !this.props.dashboard.otherPanelInFullscreen(this.props.panel);
|
||||||
}
|
}
|
||||||
@@ -124,9 +129,10 @@ export class PanelChrome extends PureComponent<Props, State> {
|
|||||||
timeSeries={timeSeries}
|
timeSeries={timeSeries}
|
||||||
timeRange={timeRange}
|
timeRange={timeRange}
|
||||||
options={panel.getOptions(plugin.exports.PanelDefaults)}
|
options={panel.getOptions(plugin.exports.PanelDefaults)}
|
||||||
width={width - 2 * variables.panelHorizontalPadding }
|
width={width - 2 * variables.panelHorizontalPadding}
|
||||||
height={height - PANEL_HEADER_HEIGHT - variables.panelVerticalPadding}
|
height={height - PANEL_HEADER_HEIGHT - variables.panelVerticalPadding}
|
||||||
renderCounter={renderCounter}
|
renderCounter={renderCounter}
|
||||||
|
onInterpolate={this.onInterpolate}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import classNames from 'classnames';
|
|||||||
|
|
||||||
import PanelHeaderCorner from './PanelHeaderCorner';
|
import PanelHeaderCorner from './PanelHeaderCorner';
|
||||||
import { PanelHeaderMenu } from './PanelHeaderMenu';
|
import { PanelHeaderMenu } from './PanelHeaderMenu';
|
||||||
|
import templateSrv from 'app/features/templating/template_srv';
|
||||||
|
|
||||||
import { DashboardModel } from 'app/features/dashboard/dashboard_model';
|
import { DashboardModel } from 'app/features/dashboard/dashboard_model';
|
||||||
import { PanelModel } from 'app/features/dashboard/panel_model';
|
import { PanelModel } from 'app/features/dashboard/panel_model';
|
||||||
@@ -45,7 +46,9 @@ export class PanelHeader extends Component<Props, State> {
|
|||||||
const isFullscreen = false;
|
const isFullscreen = false;
|
||||||
const isLoading = false;
|
const isLoading = false;
|
||||||
const panelHeaderClass = classNames({ 'panel-header': true, 'grid-drag-handle': !isFullscreen });
|
const panelHeaderClass = classNames({ 'panel-header': true, 'grid-drag-handle': !isFullscreen });
|
||||||
const { panel, dashboard, timeInfo } = this.props;
|
const { panel, dashboard, timeInfo, scopedVars } = this.props;
|
||||||
|
const title = templateSrv.replaceWithText(panel.title, scopedVars);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PanelHeaderCorner
|
<PanelHeaderCorner
|
||||||
@@ -65,7 +68,7 @@ export class PanelHeader extends Component<Props, State> {
|
|||||||
<div className="panel-title">
|
<div className="panel-title">
|
||||||
<span className="icon-gf panel-alert-icon" />
|
<span className="icon-gf panel-alert-icon" />
|
||||||
<span className="panel-title-text">
|
<span className="panel-title-text">
|
||||||
{panel.title} <span className="fa fa-caret-down panel-menu-toggle" />
|
{title} <span className="fa fa-caret-down panel-menu-toggle" />
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
{this.state.panelMenuOpen && (
|
{this.state.panelMenuOpen && (
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ export class VariableSrv {
|
|||||||
|
|
||||||
return this.$q.all(promises).then(() => {
|
return this.$q.all(promises).then(() => {
|
||||||
if (emitChangeEvents) {
|
if (emitChangeEvents) {
|
||||||
this.$rootScope.$emit('template-variable-value-updated');
|
this.$rootScope.appEvent('template-variable-value-updated');
|
||||||
this.dashboard.startRefresh();
|
this.dashboard.startRefresh();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,7 +8,10 @@ interface Props extends PanelProps<GaugeOptions> {}
|
|||||||
|
|
||||||
export class GaugePanel extends PureComponent<Props> {
|
export class GaugePanel extends PureComponent<Props> {
|
||||||
render() {
|
render() {
|
||||||
const { timeSeries, width, height } = this.props;
|
const { timeSeries, width, height, onInterpolate, options } = this.props;
|
||||||
|
|
||||||
|
const prefix = onInterpolate(options.prefix);
|
||||||
|
const suffix = onInterpolate(options.suffix);
|
||||||
|
|
||||||
const vmSeries = getTimeSeriesVMs({
|
const vmSeries = getTimeSeriesVMs({
|
||||||
timeSeries: timeSeries,
|
timeSeries: timeSeries,
|
||||||
@@ -21,6 +24,8 @@ export class GaugePanel extends PureComponent<Props> {
|
|||||||
{...this.props.options}
|
{...this.props.options}
|
||||||
width={width}
|
width={width}
|
||||||
height={height}
|
height={height}
|
||||||
|
prefix={prefix}
|
||||||
|
suffix={suffix}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,9 +80,9 @@ export class Gauge extends PureComponent<Props> {
|
|||||||
const { rangeMap, valueMap } = this.formatWithMappings(mappings, formattedValue);
|
const { rangeMap, valueMap } = this.formatWithMappings(mappings, formattedValue);
|
||||||
|
|
||||||
if (valueMap) {
|
if (valueMap) {
|
||||||
return valueMap;
|
return `${prefix} ${valueMap} ${suffix}`;
|
||||||
} else if (rangeMap) {
|
} else if (rangeMap) {
|
||||||
return rangeMap;
|
return `${prefix} ${rangeMap} ${suffix}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user