Browse Source

Merge pull request #14898 from grafana/hughag/template-variable-support-for-react-panels

Template variable support for react panels
Torkel Ödegaard 7 years ago
parent
commit
6edc4e9f02

+ 3 - 0
packages/grafana-ui/src/types/panel.ts

@@ -1,6 +1,8 @@
 import { TimeSeries, LoadingState } from './series';
 import { TimeRange } from './time';
 
+export type InterpolateFunction = (value: string, format?: string | Function) => string;
+
 export interface PanelProps<T = any> {
   timeSeries: TimeSeries[];
   timeRange: TimeRange;
@@ -9,6 +11,7 @@ export interface PanelProps<T = any> {
   renderCounter: number;
   width: number;
   height: number;
+  onInterpolate: InterpolateFunction;
 }
 
 export interface PanelOptionsProps<T = any> {

+ 7 - 1
public/app/features/dashboard/dashgrid/PanelChrome.tsx

@@ -20,6 +20,7 @@ import { PanelPlugin } from 'app/types';
 import { TimeRange } from '@grafana/ui';
 
 import variables from 'sass/_variables.scss';
+import templateSrv from 'app/features/templating/template_srv';
 
 export interface Props {
   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() {
     return !this.props.dashboard.otherPanelInFullscreen(this.props.panel);
   }
@@ -124,9 +129,10 @@ export class PanelChrome extends PureComponent<Props, State> {
                         timeSeries={timeSeries}
                         timeRange={timeRange}
                         options={panel.getOptions(plugin.exports.PanelDefaults)}
-                        width={width - 2 * variables.panelHorizontalPadding }
+                        width={width - 2 * variables.panelHorizontalPadding}
                         height={height - PANEL_HEADER_HEIGHT - variables.panelVerticalPadding}
                         renderCounter={renderCounter}
+                        onInterpolate={this.onInterpolate}
                       />
                     </div>
                   );

+ 5 - 2
public/app/features/dashboard/dashgrid/PanelHeader/PanelHeader.tsx

@@ -3,6 +3,7 @@ import classNames from 'classnames';
 
 import PanelHeaderCorner from './PanelHeaderCorner';
 import { PanelHeaderMenu } from './PanelHeaderMenu';
+import templateSrv from 'app/features/templating/template_srv';
 
 import { DashboardModel } from 'app/features/dashboard/dashboard_model';
 import { PanelModel } from 'app/features/dashboard/panel_model';
@@ -45,7 +46,9 @@ export class PanelHeader extends Component<Props, State> {
     const isFullscreen = false;
     const isLoading = false;
     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 (
       <>
         <PanelHeaderCorner
@@ -65,7 +68,7 @@ export class PanelHeader extends Component<Props, State> {
             <div className="panel-title">
               <span className="icon-gf panel-alert-icon" />
               <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>
 
               {this.state.panelMenuOpen && (

+ 1 - 1
public/app/features/templating/variable_srv.ts

@@ -132,7 +132,7 @@ export class VariableSrv {
 
     return this.$q.all(promises).then(() => {
       if (emitChangeEvents) {
-        this.$rootScope.$emit('template-variable-value-updated');
+        this.$rootScope.appEvent('template-variable-value-updated');
         this.dashboard.startRefresh();
       }
     });

+ 6 - 1
public/app/plugins/panel/gauge/GaugePanel.tsx

@@ -8,7 +8,10 @@ interface Props extends PanelProps<GaugeOptions> {}
 
 export class GaugePanel extends PureComponent<Props> {
   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({
       timeSeries: timeSeries,
@@ -21,6 +24,8 @@ export class GaugePanel extends PureComponent<Props> {
         {...this.props.options}
         width={width}
         height={height}
+        prefix={prefix}
+        suffix={suffix}
       />
     );
   }

+ 2 - 2
public/app/viz/Gauge.tsx

@@ -80,9 +80,9 @@ export class Gauge extends PureComponent<Props> {
       const { rangeMap, valueMap } = this.formatWithMappings(mappings, formattedValue);
 
       if (valueMap) {
-        return valueMap;
+        return `${prefix} ${valueMap} ${suffix}`;
       } else if (rangeMap) {
-        return rangeMap;
+        return `${prefix} ${rangeMap} ${suffix}`;
       }
     }