Browse Source

Chore: Fix noImplicitAny issues (#17636)

* noImplicitAny: TableRenderer

* noImplicitAny and add types

* HeatmapData interface

* Heatmap rendering

* Fix optional type

* Remove use of lodash
Tobias Skarhed 6 years ago
parent
commit
17826796da

+ 1 - 0
package.json

@@ -189,6 +189,7 @@
   "dependencies": {
     "@babel/polyfill": "7.2.5",
     "@torkelo/react-select": "2.4.1",
+    "@types/angular-route": "1.7.0",
     "@types/react-redux": "^7.0.8",
     "@types/reselect": "2.2.0",
     "angular": "1.6.6",

+ 29 - 43
public/app/plugins/panel/heatmap/heatmap_data_converter.ts

@@ -1,24 +1,16 @@
 import _ from 'lodash';
+import { TimeSeries } from 'app/core/core';
+import { Bucket, HeatmapCard, HeatmapCardStats, YBucket, XBucket } from './types';
 
 const VALUE_INDEX = 0;
 const TIME_INDEX = 1;
 
-interface XBucket {
-  x: number;
-  buckets: any;
-}
-
-interface YBucket {
-  y: number;
-  values: number[];
-}
-
 /**
  * Convert histogram represented by the list of series to heatmap object.
  * @param seriesList List of time series
  */
-function histogramToHeatmap(seriesList) {
-  const heatmap = {};
+function histogramToHeatmap(seriesList: TimeSeries[]) {
+  const heatmap: any = {};
 
   for (let i = 0; i < seriesList.length; i++) {
     const series = seriesList[i];
@@ -59,7 +51,7 @@ function histogramToHeatmap(seriesList) {
 /**
  * Sort series representing histogram by label value.
  */
-function sortSeriesByLabel(s1, s2) {
+function sortSeriesByLabel(s1: { label: string }, s2: { label: string }) {
   let label1, label2;
 
   try {
@@ -93,22 +85,6 @@ function parseHistogramLabel(label: string): number {
   return value;
 }
 
-interface HeatmapCard {
-  x: number;
-  y: number;
-  yBounds: {
-    top: number | null;
-    bottom: number | null;
-  };
-  values: number[];
-  count: number;
-}
-
-interface HeatmapCardStats {
-  min: number;
-  max: number;
-}
-
 /**
  * Convert buckets into linear array of "cards" - objects, represented heatmap elements.
  * @param  {Object} buckets
@@ -162,11 +138,11 @@ function convertToCards(buckets: any, hideZero = false): { cards: HeatmapCard[];
  * @param  {Number} minValue Minimum series value
  * @return {Object}          Transformed buckets
  */
-function mergeZeroBuckets(buckets, minValue) {
+function mergeZeroBuckets(buckets: any, minValue: number) {
   _.forEach(buckets, xBucket => {
     const yBuckets = xBucket.buckets;
 
-    const emptyBucket = {
+    const emptyBucket: any = {
       bounds: { bottom: 0, top: 0 },
       values: [],
       points: [],
@@ -176,7 +152,7 @@ function mergeZeroBuckets(buckets, minValue) {
     const nullBucket = yBuckets[0] || emptyBucket;
     const minBucket = yBuckets[minValue] || emptyBucket;
 
-    const newBucket = {
+    const newBucket: any = {
       y: 0,
       bounds: { bottom: minValue, top: minBucket.bounds.top || minValue },
       values: [],
@@ -228,7 +204,7 @@ function mergeZeroBuckets(buckets, minValue) {
  *   xBucketBound_N: {}
  * }
  */
-function convertToHeatMap(seriesList, yBucketSize, xBucketSize, logBase = 1) {
+function convertToHeatMap(seriesList: TimeSeries[], yBucketSize: number, xBucketSize: number, logBase = 1) {
   const heatmap = {};
 
   for (const series of seriesList) {
@@ -264,7 +240,7 @@ function convertToHeatMap(seriesList, yBucketSize, xBucketSize, logBase = 1) {
   return heatmap;
 }
 
-function pushToXBuckets(buckets, point, bucketNum, seriesName) {
+function pushToXBuckets(buckets: any, point: any[], bucketNum: number, seriesName: string) {
   const value = point[VALUE_INDEX];
   if (value === null || value === undefined || isNaN(value)) {
     return;
@@ -285,7 +261,13 @@ function pushToXBuckets(buckets, point, bucketNum, seriesName) {
   }
 }
 
-function pushToYBuckets(buckets, bucketNum, value, point, bounds) {
+function pushToYBuckets(
+  buckets: Bucket,
+  bucketNum: number,
+  value: any,
+  point: string[],
+  bounds: { bottom: number; top: number }
+) {
   let count = 1;
   // Use the 3rd argument as scale/count
   if (point.length > 3) {
@@ -306,7 +288,7 @@ function pushToYBuckets(buckets, bucketNum, value, point, bounds) {
   }
 }
 
-function getValueBucketBound(value, yBucketSize, logBase) {
+function getValueBucketBound(value: any, yBucketSize: number, logBase: number) {
   if (logBase === 1) {
     return getBucketBound(value, yBucketSize);
   } else {
@@ -317,7 +299,7 @@ function getValueBucketBound(value, yBucketSize, logBase) {
 /**
  * Find bucket for given value (for linear scale)
  */
-function getBucketBounds(value, bucketSize) {
+function getBucketBounds(value: number, bucketSize: number) {
   let bottom, top;
   bottom = Math.floor(value / bucketSize) * bucketSize;
   top = (Math.floor(value / bucketSize) + 1) * bucketSize;
@@ -325,12 +307,12 @@ function getBucketBounds(value, bucketSize) {
   return { bottom, top };
 }
 
-function getBucketBound(value, bucketSize) {
+function getBucketBound(value: number, bucketSize: number) {
   const bounds = getBucketBounds(value, bucketSize);
   return bounds.bottom;
 }
 
-function convertToValueBuckets(xBucket, bucketSize) {
+function convertToValueBuckets(xBucket: { values: any; points: any }, bucketSize: number) {
   const values = xBucket.values;
   const points = xBucket.points;
   const buckets = {};
@@ -347,7 +329,7 @@ function convertToValueBuckets(xBucket, bucketSize) {
 /**
  * Find bucket for given value (for log scales)
  */
-function getLogScaleBucketBounds(value, yBucketSplitFactor, logBase) {
+function getLogScaleBucketBounds(value: number, yBucketSplitFactor: number, logBase: number) {
   let top, bottom;
   if (value === 0) {
     return { bottom: 0, top: 0 };
@@ -371,12 +353,16 @@ function getLogScaleBucketBounds(value, yBucketSplitFactor, logBase) {
   return { bottom, top };
 }
 
-function getLogScaleBucketBound(value, yBucketSplitFactor, logBase) {
+function getLogScaleBucketBound(value: number, yBucketSplitFactor: number, logBase: number) {
   const bounds = getLogScaleBucketBounds(value, yBucketSplitFactor, logBase);
   return bounds.bottom;
 }
 
-function convertToLogScaleValueBuckets(xBucket, yBucketSplitFactor, logBase) {
+function convertToLogScaleValueBuckets(
+  xBucket: { values: any; points: any },
+  yBucketSplitFactor: number,
+  logBase: number
+) {
   const values = xBucket.values;
   const points = xBucket.points;
 
@@ -395,7 +381,7 @@ function convertToLogScaleValueBuckets(xBucket, yBucketSplitFactor, logBase) {
  * @param value
  * @param base logarithm base
  */
-function logp(value, base) {
+function logp(value: number, base: number) {
   return Math.log(value) / Math.log(base);
 }
 

+ 33 - 33
public/app/plugins/panel/heatmap/rendering.ts

@@ -19,7 +19,7 @@ const MIN_CARD_SIZE = 1,
   Y_AXIS_TICK_PADDING = 5,
   MIN_SELECTION_WIDTH = 2;
 
-export default function rendering(scope, elem, attrs, ctrl) {
+export default function rendering(scope: any, elem: any, attrs: any, ctrl: any) {
   return new HeatmapRenderer(scope, elem, attrs, ctrl);
 }
 export class HeatmapRenderer {
@@ -51,7 +51,7 @@ export class HeatmapRenderer {
   padding: any;
   margin: any;
   dataRangeWidingFactor: number;
-  constructor(private scope, private elem, attrs, private ctrl) {
+  constructor(private scope: any, private elem: any, attrs: any, private ctrl: any) {
     // $heatmap is JQuery object, but heatmap is D3
     this.$heatmap = this.elem.find('.heatmap-panel');
     this.tooltip = new HeatmapTooltip(this.$heatmap, this.scope);
@@ -89,7 +89,7 @@ export class HeatmapRenderer {
     this.clearCrosshair();
   }
 
-  onGraphHover(event) {
+  onGraphHover(event: { pos: any }) {
     this.drawSharedCrosshair(event.pos);
   }
 
@@ -116,7 +116,7 @@ export class HeatmapRenderer {
     }
   }
 
-  getYAxisWidth(elem) {
+  getYAxisWidth(elem: any) {
     const axisText = elem.selectAll('.axis-y text').nodes();
     const maxTextWidth = _.max(
       _.map(axisText, text => {
@@ -128,7 +128,7 @@ export class HeatmapRenderer {
     return maxTextWidth;
   }
 
-  getXAxisHeight(elem) {
+  getXAxisHeight(elem: any) {
     const axisLine = elem.select('.axis-x line');
     if (!axisLine.empty()) {
       const axisLinePosition = parseFloat(elem.select('.axis-x line').attr('y2'));
@@ -244,7 +244,7 @@ export class HeatmapRenderer {
   }
 
   // Wide Y values range and anjust to bucket size
-  wideYAxisRange(min, max, tickInterval) {
+  wideYAxisRange(min: number, max: number, tickInterval: number) {
     const yWiding = (max * (this.dataRangeWidingFactor - 1) - min * (this.dataRangeWidingFactor - 1)) / 2;
     let yMin, yMax;
 
@@ -349,7 +349,7 @@ export class HeatmapRenderer {
     this.ctrl.decimals = decimals;
 
     const tickValueFormatter = this.tickValueFormatter.bind(this);
-    function tickFormatter(valIndex) {
+    function tickFormatter(valIndex: string) {
       let valueFormatted = tsBuckets[valIndex];
       if (!_.isNaN(_.toNumber(valueFormatted)) && valueFormatted !== '') {
         // Try to format numeric tick labels
@@ -393,7 +393,7 @@ export class HeatmapRenderer {
   }
 
   // Adjust data range to log base
-  adjustLogRange(min, max, logBase) {
+  adjustLogRange(min: number, max: number, logBase: number) {
     let yMin = this.data.heatmapStats.minLog;
     if (this.data.heatmapStats.minLog > 1 || !this.data.heatmapStats.minLog) {
       yMin = 1;
@@ -407,15 +407,15 @@ export class HeatmapRenderer {
     return { yMin, yMax };
   }
 
-  adjustLogMax(max, base) {
+  adjustLogMax(max: number, base: number) {
     return Math.pow(base, Math.ceil(ticksUtils.logp(max, base)));
   }
 
-  adjustLogMin(min, base) {
+  adjustLogMin(min: number, base: number) {
     return Math.pow(base, Math.floor(ticksUtils.logp(min, base)));
   }
 
-  logScaleTickValues(domain, base) {
+  logScaleTickValues(domain: any[], base: number) {
     const domainMin = domain[0];
     const domainMax = domain[1];
     const tickValues = [];
@@ -437,9 +437,9 @@ export class HeatmapRenderer {
     return tickValues;
   }
 
-  tickValueFormatter(decimals, scaledDecimals = null) {
+  tickValueFormatter(decimals: number, scaledDecimals: any = null) {
     const format = this.panel.yAxis.format;
-    return value => {
+    return (value: any) => {
       try {
         return format !== 'none' ? getValueFormat(format)(value, decimals, scaledDecimals) : value;
       } catch (err) {
@@ -555,17 +555,17 @@ export class HeatmapRenderer {
 
     const $cards = this.$heatmap.find('.heatmap-card');
     $cards
-      .on('mouseenter', event => {
+      .on('mouseenter', (event: any) => {
         this.tooltip.mouseOverBucket = true;
         this.highlightCard(event);
       })
-      .on('mouseleave', event => {
+      .on('mouseleave', (event: any) => {
         this.tooltip.mouseOverBucket = false;
         this.resetCardHighLight(event);
       });
   }
 
-  highlightCard(event) {
+  highlightCard(event: any) {
     const color = d3.select(event.target).style('fill');
     const highlightColor = d3.color(color).darker(2);
     const strokeColor = d3.color(color).brighter(4);
@@ -577,7 +577,7 @@ export class HeatmapRenderer {
       .style('stroke-width', 1);
   }
 
-  resetCardHighLight(event) {
+  resetCardHighLight(event: any) {
     d3.select(event.target)
       .style('fill', this.tooltip.originalFillColor)
       .style('stroke', this.tooltip.originalFillColor)
@@ -599,7 +599,7 @@ export class HeatmapRenderer {
     this.cardHeight = yGridSize ? yGridSize - this.cardPadding * 2 : 0;
   }
 
-  getCardX(d) {
+  getCardX(d: { x: any }) {
     let x;
     if (this.xScale(d.x) < 0) {
       // Cut card left to prevent overlay
@@ -611,7 +611,7 @@ export class HeatmapRenderer {
     return x;
   }
 
-  getCardWidth(d) {
+  getCardWidth(d: { x: any }) {
     let w = this.cardWidth;
     if (this.xScale(d.x) < 0) {
       // Cut card left to prevent overlay
@@ -626,7 +626,7 @@ export class HeatmapRenderer {
     return w;
   }
 
-  getCardY(d) {
+  getCardY(d: { y: number }) {
     let y = this.yScale(d.y) + this.chartTop - this.cardHeight - this.cardPadding;
     if (this.panel.yAxis.logBase !== 1 && d.y === 0) {
       y = this.chartBottom - this.cardHeight - this.cardPadding;
@@ -639,7 +639,7 @@ export class HeatmapRenderer {
     return y;
   }
 
-  getCardHeight(d) {
+  getCardHeight(d: { y: number }) {
     const y = this.yScale(d.y) + this.chartTop - this.cardHeight - this.cardPadding;
     let h = this.cardHeight;
 
@@ -664,7 +664,7 @@ export class HeatmapRenderer {
     return h;
   }
 
-  getCardColor(d) {
+  getCardColor(d: { count: any }) {
     if (this.panel.color.mode === 'opacity') {
       return getColorFromHexRgbOrName(
         this.panel.color.cardColor,
@@ -675,7 +675,7 @@ export class HeatmapRenderer {
     }
   }
 
-  getCardOpacity(d) {
+  getCardOpacity(d: { count: any }) {
     if (this.panel.color.mode === 'opacity') {
       return this.opacityScale(d.count);
     } else {
@@ -683,14 +683,14 @@ export class HeatmapRenderer {
     }
   }
 
-  getEventOffset(event) {
+  getEventOffset(event: any) {
     const elemOffset = this.$heatmap.offset();
     const x = Math.floor(event.clientX - elemOffset.left);
     const y = Math.floor(event.clientY - elemOffset.top);
     return { x, y };
   }
 
-  onMouseDown(event) {
+  onMouseDown(event: any) {
     const offset = this.getEventOffset(event);
     this.selection.active = true;
     this.selection.x1 = offset.x;
@@ -726,7 +726,7 @@ export class HeatmapRenderer {
     this.clearCrosshair();
   }
 
-  onMouseMove(event) {
+  onMouseMove(event: any) {
     if (!this.heatmap) {
       return;
     }
@@ -747,10 +747,10 @@ export class HeatmapRenderer {
     }
   }
 
-  getEventPos(event, offset) {
+  getEventPos(event: { pageX: any; pageY: any }, offset: { x: any; y: any }) {
     const x = this.xScale.invert(offset.x - this.yAxisWidth).valueOf();
     const y = this.yScale.invert(offset.y - this.chartTop);
-    const pos = {
+    const pos: any = {
       pageX: event.pageX,
       pageY: event.pageY,
       x: x,
@@ -764,20 +764,20 @@ export class HeatmapRenderer {
     return pos;
   }
 
-  emitGraphHoverEvent(pos) {
+  emitGraphHoverEvent(pos: { panelRelY: number; offset: { y: number } }) {
     // Set minimum offset to prevent showing legend from another panel
     pos.panelRelY = Math.max(pos.offset.y / this.height, 0.001);
     // broadcast to other graph panels that we are hovering
     appEvents.emit('graph-hover', { pos: pos, panel: this.panel });
   }
 
-  limitSelection(x2) {
+  limitSelection(x2: number) {
     x2 = Math.max(x2, this.yAxisWidth);
     x2 = Math.min(x2, this.chartWidth + this.yAxisWidth);
     return x2;
   }
 
-  drawSelection(posX1, posX2) {
+  drawSelection(posX1: number, posX2: number) {
     if (this.heatmap) {
       this.heatmap.selectAll('.heatmap-selection').remove();
       const selectionX = Math.min(posX1, posX2);
@@ -804,7 +804,7 @@ export class HeatmapRenderer {
     }
   }
 
-  drawCrosshair(position) {
+  drawCrosshair(position: number) {
     if (this.heatmap) {
       this.heatmap.selectAll('.heatmap-crosshair').remove();
 
@@ -825,7 +825,7 @@ export class HeatmapRenderer {
     }
   }
 
-  drawSharedCrosshair(pos) {
+  drawSharedCrosshair(pos: { x: any }) {
     if (this.heatmap && this.ctrl.dashboard.graphTooltip !== 0) {
       const posX = this.xScale(pos.x) + this.yAxisWidth;
       this.drawCrosshair(posX);

+ 3 - 2
public/app/plugins/panel/heatmap/specs/heatmap_data_converter.test.ts

@@ -8,6 +8,7 @@ import {
   calculateBucketSize,
   isHeatmapDataEqual,
 } from '../heatmap_data_converter';
+import { HeatmapData } from '../types';
 
 describe('isHeatmapDataEqual', () => {
   const ctx: any = {};
@@ -248,7 +249,7 @@ describe('Histogram converter', () => {
     beforeEach(() => {});
 
     it('should build proper heatmap data', () => {
-      const expectedHeatmap = {
+      const expectedHeatmap: HeatmapData = {
         '1422774000000': {
           x: 1422774000000,
           buckets: {
@@ -322,7 +323,7 @@ describe('Histogram converter', () => {
 });
 
 describe('convertToCards', () => {
-  let buckets = {};
+  let buckets: HeatmapData = {};
 
   beforeEach(() => {
     buckets = {

+ 42 - 0
public/app/plugins/panel/heatmap/types.ts

@@ -0,0 +1,42 @@
+export interface Bucket {
+  [x: string]: {
+    y: any;
+    bounds: any;
+    values: any[];
+    points?: any[];
+    count: number;
+  };
+}
+
+export interface XBucket {
+  x: number;
+  buckets: any;
+}
+
+export interface YBucket {
+  y: number;
+  values: number[];
+}
+
+export interface HeatmapCard {
+  x: number;
+  y: number;
+  yBounds: {
+    top: number | null;
+    bottom: number | null;
+  };
+  values: number[];
+  count: number;
+}
+
+export interface HeatmapCardStats {
+  min: number;
+  max: number;
+}
+
+export interface HeatmapData {
+  [key: string]: {
+    x: number;
+    buckets: Bucket;
+  };
+}

+ 25 - 25
public/app/plugins/panel/table/renderer.ts

@@ -1,25 +1,27 @@
 import _ from 'lodash';
-import { getValueFormat, getColorFromHexRgbOrName, GrafanaThemeType } from '@grafana/ui';
+import { getValueFormat, getColorFromHexRgbOrName, GrafanaThemeType, ScopedVars } from '@grafana/ui';
 import { stringToJsRegex } from '@grafana/data';
 import { ColumnStyle } from '@grafana/ui/src/components/Table/TableCellBuilder';
 import { dateTime } from '@grafana/ui/src/utils/moment_wrapper';
+import { TemplateSrv } from 'app/features/templating/template_srv';
+import { TableRenderModel, ColumnRender } from './types';
 
 export class TableRenderer {
   formatters: any[];
   colorState: any;
 
   constructor(
-    private panel,
-    private table,
-    private isUtc,
-    private sanitize,
-    private templateSrv,
+    private panel: { styles: ColumnStyle[]; pageSize: number },
+    private table: TableRenderModel,
+    private isUtc: boolean,
+    private sanitize: (v: any) => any,
+    private templateSrv: TemplateSrv,
     private theme?: GrafanaThemeType
   ) {
     this.initColumns();
   }
 
-  setTable(table) {
+  setTable(table: TableRenderModel) {
     this.table = table;
 
     this.initColumns();
@@ -52,7 +54,7 @@ export class TableRenderer {
     }
   }
 
-  getColorForValue(value, style: ColumnStyle) {
+  getColorForValue(value: number, style: ColumnStyle) {
     if (!style.thresholds) {
       return null;
     }
@@ -64,7 +66,7 @@ export class TableRenderer {
     return getColorFromHexRgbOrName(_.first(style.colors), this.theme);
   }
 
-  defaultCellFormatter(v, style: ColumnStyle) {
+  defaultCellFormatter(v: any, style: ColumnStyle) {
     if (v === null || v === void 0 || v === undefined) {
       return '';
     }
@@ -80,19 +82,17 @@ export class TableRenderer {
     }
   }
 
-  createColumnFormatter(column) {
+  createColumnFormatter(column: ColumnRender) {
     if (!column.style) {
       return this.defaultCellFormatter;
     }
 
     if (column.style.type === 'hidden') {
-      return v => {
-        return undefined;
-      };
+      return (v: any): undefined => undefined;
     }
 
     if (column.style.type === 'date') {
-      return v => {
+      return (v: any) => {
         if (v === undefined || v === null) {
           return '-';
         }
@@ -117,7 +117,7 @@ export class TableRenderer {
     }
 
     if (column.style.type === 'string') {
-      return v => {
+      return (v: any): any => {
         if (_.isArray(v)) {
           v = v.join(', ');
         }
@@ -173,7 +173,7 @@ export class TableRenderer {
     if (column.style.type === 'number') {
       const valueFormatter = getValueFormat(column.unit || column.style.unit);
 
-      return v => {
+      return (v: any): any => {
         if (v === null || v === void 0) {
           return '-';
         }
@@ -187,12 +187,12 @@ export class TableRenderer {
       };
     }
 
-    return value => {
+    return (value: any) => {
       return this.defaultCellFormatter(value, column.style);
     };
   }
 
-  setColorState(value, style: ColumnStyle) {
+  setColorState(value: any, style: ColumnStyle) {
     if (!style.colorMode) {
       return;
     }
@@ -209,22 +209,22 @@ export class TableRenderer {
     this.colorState[style.colorMode] = this.getColorForValue(numericValue, style);
   }
 
-  renderRowVariables(rowIndex) {
-    const scopedVars = {};
+  renderRowVariables(rowIndex: number) {
+    const scopedVars: ScopedVars = {};
     let cellVariable;
     const row = this.table.rows[rowIndex];
     for (let i = 0; i < row.length; i++) {
       cellVariable = `__cell_${i}`;
-      scopedVars[cellVariable] = { value: row[i] };
+      scopedVars[cellVariable] = { value: row[i], text: row[i] ? row[i].toString() : '' };
     }
     return scopedVars;
   }
 
-  formatColumnValue(colIndex, value) {
+  formatColumnValue(colIndex: number, value: any) {
     return this.formatters[colIndex] ? this.formatters[colIndex](value) : value;
   }
 
-  renderCell(columnIndex, rowIndex, value, addWidthHack = false) {
+  renderCell(columnIndex: number, rowIndex: number, value: any, addWidthHack = false) {
     value = this.formatColumnValue(columnIndex, value);
 
     const column = this.table.columns[columnIndex];
@@ -267,7 +267,7 @@ export class TableRenderer {
     if (column.style && column.style.link) {
       // Render cell as link
       const scopedVars = this.renderRowVariables(rowIndex);
-      scopedVars['__cell'] = { value: value };
+      scopedVars['__cell'] = { value: value, text: value ? value.toString() : '' };
 
       const cellLink = this.templateSrv.replace(column.style.linkUrl, scopedVars, encodeURIComponent);
       const cellLinkTooltip = this.templateSrv.replace(column.style.linkTooltip, scopedVars);
@@ -305,7 +305,7 @@ export class TableRenderer {
     return columnHtml;
   }
 
-  render(page) {
+  render(page: number) {
     const pageSize = this.panel.pageSize || 100;
     const startPos = page * pageSize;
     const endPos = Math.min(startPos + pageSize, this.table.rows.length);

+ 5 - 4
public/app/plugins/panel/table/specs/renderer.test.ts

@@ -1,7 +1,7 @@
 import _ from 'lodash';
 import TableModel from 'app/core/table_model';
 import { TableRenderer } from '../renderer';
-import { getColorDefinitionByName } from '@grafana/ui';
+import { getColorDefinitionByName, ScopedVars } from '@grafana/ui';
 
 describe('when rendering table', () => {
   const SemiDarkOrange = getColorDefinitionByName('semi-dark-orange');
@@ -166,12 +166,12 @@ describe('when rendering table', () => {
       ],
     };
 
-    const sanitize = value => {
+    const sanitize = (value: any): string => {
       return 'sanitized';
     };
 
     const templateSrv = {
-      replace: (value, scopedVars) => {
+      replace: (value: any, scopedVars: ScopedVars) => {
         if (scopedVars) {
           // For testing variables replacement in link
           _.each(scopedVars, (val, key) => {
@@ -182,6 +182,7 @@ describe('when rendering table', () => {
       },
     };
 
+    //@ts-ignore
     const renderer = new TableRenderer(panel, table, 'utc', sanitize, templateSrv);
 
     it('time column should be formated', () => {
@@ -386,6 +387,6 @@ describe('when rendering table', () => {
   });
 });
 
-function normalize(str) {
+function normalize(str: string) {
   return str.replace(/\s+/gm, ' ').trim();
 }

+ 13 - 0
public/app/plugins/panel/table/types.ts

@@ -1,7 +1,20 @@
 import TableModel from 'app/core/table_model';
+import { Column } from '@grafana/ui';
+import { ColumnStyle } from '@grafana/ui/src/components/Table/TableCellBuilder';
 
 export interface TableTransform {
   description: string;
   getColumns(data?: any): any[];
   transform(data: any, panel: any, model: TableModel): void;
 }
+
+export interface ColumnRender extends Column {
+  title: string;
+  style: ColumnStyle;
+  hidden: boolean;
+}
+
+export interface TableRenderModel {
+  columns: ColumnRender[];
+  rows: any[][];
+}

+ 1 - 1
public/app/plugins/panel/table2/TablePanelEditor.tsx

@@ -19,7 +19,7 @@ export class TablePanelEditor extends PureComponent<PanelEditorProps<Options>> {
     this.props.onOptionsChange({ ...this.props.options, rotate: !this.props.options.rotate });
   };
 
-  onFixedColumnsChange = ({ target }) => {
+  onFixedColumnsChange = ({ target }: any) => {
     this.props.onOptionsChange({ ...this.props.options, fixedColumns: target.value });
   };
 

+ 1 - 1
public/app/plugins/panel/text2/TextPanel.tsx

@@ -19,7 +19,7 @@ interface State {
 export class TextPanel extends PureComponent<Props, State> {
   remarkable: Remarkable;
 
-  constructor(props) {
+  constructor(props: Props) {
     super(props);
 
     this.state = {

+ 3 - 1
public/app/routes/routes.ts

@@ -25,17 +25,19 @@ import DashboardPage from '../features/dashboard/containers/DashboardPage';
 import PluginPage from '../features/plugins/PluginPage';
 import AppRootPage from 'app/features/plugins/AppRootPage';
 import config from 'app/core/config';
+import { route, ILocationProvider } from 'angular';
 
 // Types
 import { DashboardRouteInfo } from 'app/types';
 
 /** @ngInject */
-export function setupAngularRoutes($routeProvider, $locationProvider) {
+export function setupAngularRoutes($routeProvider: route.IRouteProvider, $locationProvider: ILocationProvider) {
   $locationProvider.html5Mode(true);
 
   $routeProvider
     .when('/', {
       template: '<react-container />',
+      //@ts-ignore
       pageClass: 'page-dashboard',
       routeInfo: DashboardRouteInfo.Home,
       reloadOnSearch: false,

+ 8 - 1
yarn.lock

@@ -1664,7 +1664,14 @@
     react-input-autosize "^2.2.1"
     react-transition-group "^2.2.1"
 
-"@types/angular@1.6.54":
+"@types/angular-route@1.7.0":
+  version "1.7.0"
+  resolved "https://registry.yarnpkg.com/@types/angular-route/-/angular-route-1.7.0.tgz#ba12d09df1aac3c88e3684500001daedfc97fb69"
+  integrity sha512-gctkSXUY7hDwFeW8il7f3+sdMmds0JaMnHvrZmqX79DHXf2D72+SHxJHIt5i6+0BrhoqdWdpgziSxuKnkAUAQw==
+  dependencies:
+    "@types/angular" "*"
+
+"@types/angular@*", "@types/angular@1.6.54":
   version "1.6.54"
   resolved "https://registry.yarnpkg.com/@types/angular/-/angular-1.6.54.tgz#f9d5a03e4da7b021a6dabe5d63e899ed4567a5bd"