mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Chore: Fix noImplicitAny issues (#17636)
* noImplicitAny: TableRenderer * noImplicitAny and add types * HeatmapData interface * Heatmap rendering * Fix optional type * Remove use of lodash
This commit is contained in:
@@ -189,6 +189,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/polyfill": "7.2.5",
|
"@babel/polyfill": "7.2.5",
|
||||||
"@torkelo/react-select": "2.4.1",
|
"@torkelo/react-select": "2.4.1",
|
||||||
|
"@types/angular-route": "1.7.0",
|
||||||
"@types/react-redux": "^7.0.8",
|
"@types/react-redux": "^7.0.8",
|
||||||
"@types/reselect": "2.2.0",
|
"@types/reselect": "2.2.0",
|
||||||
"angular": "1.6.6",
|
"angular": "1.6.6",
|
||||||
|
@@ -1,24 +1,16 @@
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
import { TimeSeries } from 'app/core/core';
|
||||||
|
import { Bucket, HeatmapCard, HeatmapCardStats, YBucket, XBucket } from './types';
|
||||||
|
|
||||||
const VALUE_INDEX = 0;
|
const VALUE_INDEX = 0;
|
||||||
const TIME_INDEX = 1;
|
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.
|
* Convert histogram represented by the list of series to heatmap object.
|
||||||
* @param seriesList List of time series
|
* @param seriesList List of time series
|
||||||
*/
|
*/
|
||||||
function histogramToHeatmap(seriesList) {
|
function histogramToHeatmap(seriesList: TimeSeries[]) {
|
||||||
const heatmap = {};
|
const heatmap: any = {};
|
||||||
|
|
||||||
for (let i = 0; i < seriesList.length; i++) {
|
for (let i = 0; i < seriesList.length; i++) {
|
||||||
const series = seriesList[i];
|
const series = seriesList[i];
|
||||||
@@ -59,7 +51,7 @@ function histogramToHeatmap(seriesList) {
|
|||||||
/**
|
/**
|
||||||
* Sort series representing histogram by label value.
|
* Sort series representing histogram by label value.
|
||||||
*/
|
*/
|
||||||
function sortSeriesByLabel(s1, s2) {
|
function sortSeriesByLabel(s1: { label: string }, s2: { label: string }) {
|
||||||
let label1, label2;
|
let label1, label2;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -93,22 +85,6 @@ function parseHistogramLabel(label: string): number {
|
|||||||
return value;
|
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.
|
* Convert buckets into linear array of "cards" - objects, represented heatmap elements.
|
||||||
* @param {Object} buckets
|
* @param {Object} buckets
|
||||||
@@ -162,11 +138,11 @@ function convertToCards(buckets: any, hideZero = false): { cards: HeatmapCard[];
|
|||||||
* @param {Number} minValue Minimum series value
|
* @param {Number} minValue Minimum series value
|
||||||
* @return {Object} Transformed buckets
|
* @return {Object} Transformed buckets
|
||||||
*/
|
*/
|
||||||
function mergeZeroBuckets(buckets, minValue) {
|
function mergeZeroBuckets(buckets: any, minValue: number) {
|
||||||
_.forEach(buckets, xBucket => {
|
_.forEach(buckets, xBucket => {
|
||||||
const yBuckets = xBucket.buckets;
|
const yBuckets = xBucket.buckets;
|
||||||
|
|
||||||
const emptyBucket = {
|
const emptyBucket: any = {
|
||||||
bounds: { bottom: 0, top: 0 },
|
bounds: { bottom: 0, top: 0 },
|
||||||
values: [],
|
values: [],
|
||||||
points: [],
|
points: [],
|
||||||
@@ -176,7 +152,7 @@ function mergeZeroBuckets(buckets, minValue) {
|
|||||||
const nullBucket = yBuckets[0] || emptyBucket;
|
const nullBucket = yBuckets[0] || emptyBucket;
|
||||||
const minBucket = yBuckets[minValue] || emptyBucket;
|
const minBucket = yBuckets[minValue] || emptyBucket;
|
||||||
|
|
||||||
const newBucket = {
|
const newBucket: any = {
|
||||||
y: 0,
|
y: 0,
|
||||||
bounds: { bottom: minValue, top: minBucket.bounds.top || minValue },
|
bounds: { bottom: minValue, top: minBucket.bounds.top || minValue },
|
||||||
values: [],
|
values: [],
|
||||||
@@ -228,7 +204,7 @@ function mergeZeroBuckets(buckets, minValue) {
|
|||||||
* xBucketBound_N: {}
|
* xBucketBound_N: {}
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
function convertToHeatMap(seriesList, yBucketSize, xBucketSize, logBase = 1) {
|
function convertToHeatMap(seriesList: TimeSeries[], yBucketSize: number, xBucketSize: number, logBase = 1) {
|
||||||
const heatmap = {};
|
const heatmap = {};
|
||||||
|
|
||||||
for (const series of seriesList) {
|
for (const series of seriesList) {
|
||||||
@@ -264,7 +240,7 @@ function convertToHeatMap(seriesList, yBucketSize, xBucketSize, logBase = 1) {
|
|||||||
return heatmap;
|
return heatmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
function pushToXBuckets(buckets, point, bucketNum, seriesName) {
|
function pushToXBuckets(buckets: any, point: any[], bucketNum: number, seriesName: string) {
|
||||||
const value = point[VALUE_INDEX];
|
const value = point[VALUE_INDEX];
|
||||||
if (value === null || value === undefined || isNaN(value)) {
|
if (value === null || value === undefined || isNaN(value)) {
|
||||||
return;
|
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;
|
let count = 1;
|
||||||
// Use the 3rd argument as scale/count
|
// Use the 3rd argument as scale/count
|
||||||
if (point.length > 3) {
|
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) {
|
if (logBase === 1) {
|
||||||
return getBucketBound(value, yBucketSize);
|
return getBucketBound(value, yBucketSize);
|
||||||
} else {
|
} else {
|
||||||
@@ -317,7 +299,7 @@ function getValueBucketBound(value, yBucketSize, logBase) {
|
|||||||
/**
|
/**
|
||||||
* Find bucket for given value (for linear scale)
|
* Find bucket for given value (for linear scale)
|
||||||
*/
|
*/
|
||||||
function getBucketBounds(value, bucketSize) {
|
function getBucketBounds(value: number, bucketSize: number) {
|
||||||
let bottom, top;
|
let bottom, top;
|
||||||
bottom = Math.floor(value / bucketSize) * bucketSize;
|
bottom = Math.floor(value / bucketSize) * bucketSize;
|
||||||
top = (Math.floor(value / bucketSize) + 1) * bucketSize;
|
top = (Math.floor(value / bucketSize) + 1) * bucketSize;
|
||||||
@@ -325,12 +307,12 @@ function getBucketBounds(value, bucketSize) {
|
|||||||
return { bottom, top };
|
return { bottom, top };
|
||||||
}
|
}
|
||||||
|
|
||||||
function getBucketBound(value, bucketSize) {
|
function getBucketBound(value: number, bucketSize: number) {
|
||||||
const bounds = getBucketBounds(value, bucketSize);
|
const bounds = getBucketBounds(value, bucketSize);
|
||||||
return bounds.bottom;
|
return bounds.bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
function convertToValueBuckets(xBucket, bucketSize) {
|
function convertToValueBuckets(xBucket: { values: any; points: any }, bucketSize: number) {
|
||||||
const values = xBucket.values;
|
const values = xBucket.values;
|
||||||
const points = xBucket.points;
|
const points = xBucket.points;
|
||||||
const buckets = {};
|
const buckets = {};
|
||||||
@@ -347,7 +329,7 @@ function convertToValueBuckets(xBucket, bucketSize) {
|
|||||||
/**
|
/**
|
||||||
* Find bucket for given value (for log scales)
|
* Find bucket for given value (for log scales)
|
||||||
*/
|
*/
|
||||||
function getLogScaleBucketBounds(value, yBucketSplitFactor, logBase) {
|
function getLogScaleBucketBounds(value: number, yBucketSplitFactor: number, logBase: number) {
|
||||||
let top, bottom;
|
let top, bottom;
|
||||||
if (value === 0) {
|
if (value === 0) {
|
||||||
return { bottom: 0, top: 0 };
|
return { bottom: 0, top: 0 };
|
||||||
@@ -371,12 +353,16 @@ function getLogScaleBucketBounds(value, yBucketSplitFactor, logBase) {
|
|||||||
return { bottom, top };
|
return { bottom, top };
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLogScaleBucketBound(value, yBucketSplitFactor, logBase) {
|
function getLogScaleBucketBound(value: number, yBucketSplitFactor: number, logBase: number) {
|
||||||
const bounds = getLogScaleBucketBounds(value, yBucketSplitFactor, logBase);
|
const bounds = getLogScaleBucketBounds(value, yBucketSplitFactor, logBase);
|
||||||
return bounds.bottom;
|
return bounds.bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
function convertToLogScaleValueBuckets(xBucket, yBucketSplitFactor, logBase) {
|
function convertToLogScaleValueBuckets(
|
||||||
|
xBucket: { values: any; points: any },
|
||||||
|
yBucketSplitFactor: number,
|
||||||
|
logBase: number
|
||||||
|
) {
|
||||||
const values = xBucket.values;
|
const values = xBucket.values;
|
||||||
const points = xBucket.points;
|
const points = xBucket.points;
|
||||||
|
|
||||||
@@ -395,7 +381,7 @@ function convertToLogScaleValueBuckets(xBucket, yBucketSplitFactor, logBase) {
|
|||||||
* @param value
|
* @param value
|
||||||
* @param base logarithm base
|
* @param base logarithm base
|
||||||
*/
|
*/
|
||||||
function logp(value, base) {
|
function logp(value: number, base: number) {
|
||||||
return Math.log(value) / Math.log(base);
|
return Math.log(value) / Math.log(base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -19,7 +19,7 @@ const MIN_CARD_SIZE = 1,
|
|||||||
Y_AXIS_TICK_PADDING = 5,
|
Y_AXIS_TICK_PADDING = 5,
|
||||||
MIN_SELECTION_WIDTH = 2;
|
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);
|
return new HeatmapRenderer(scope, elem, attrs, ctrl);
|
||||||
}
|
}
|
||||||
export class HeatmapRenderer {
|
export class HeatmapRenderer {
|
||||||
@@ -51,7 +51,7 @@ export class HeatmapRenderer {
|
|||||||
padding: any;
|
padding: any;
|
||||||
margin: any;
|
margin: any;
|
||||||
dataRangeWidingFactor: number;
|
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
|
// $heatmap is JQuery object, but heatmap is D3
|
||||||
this.$heatmap = this.elem.find('.heatmap-panel');
|
this.$heatmap = this.elem.find('.heatmap-panel');
|
||||||
this.tooltip = new HeatmapTooltip(this.$heatmap, this.scope);
|
this.tooltip = new HeatmapTooltip(this.$heatmap, this.scope);
|
||||||
@@ -89,7 +89,7 @@ export class HeatmapRenderer {
|
|||||||
this.clearCrosshair();
|
this.clearCrosshair();
|
||||||
}
|
}
|
||||||
|
|
||||||
onGraphHover(event) {
|
onGraphHover(event: { pos: any }) {
|
||||||
this.drawSharedCrosshair(event.pos);
|
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 axisText = elem.selectAll('.axis-y text').nodes();
|
||||||
const maxTextWidth = _.max(
|
const maxTextWidth = _.max(
|
||||||
_.map(axisText, text => {
|
_.map(axisText, text => {
|
||||||
@@ -128,7 +128,7 @@ export class HeatmapRenderer {
|
|||||||
return maxTextWidth;
|
return maxTextWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
getXAxisHeight(elem) {
|
getXAxisHeight(elem: any) {
|
||||||
const axisLine = elem.select('.axis-x line');
|
const axisLine = elem.select('.axis-x line');
|
||||||
if (!axisLine.empty()) {
|
if (!axisLine.empty()) {
|
||||||
const axisLinePosition = parseFloat(elem.select('.axis-x line').attr('y2'));
|
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
|
// 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;
|
const yWiding = (max * (this.dataRangeWidingFactor - 1) - min * (this.dataRangeWidingFactor - 1)) / 2;
|
||||||
let yMin, yMax;
|
let yMin, yMax;
|
||||||
|
|
||||||
@@ -349,7 +349,7 @@ export class HeatmapRenderer {
|
|||||||
this.ctrl.decimals = decimals;
|
this.ctrl.decimals = decimals;
|
||||||
|
|
||||||
const tickValueFormatter = this.tickValueFormatter.bind(this);
|
const tickValueFormatter = this.tickValueFormatter.bind(this);
|
||||||
function tickFormatter(valIndex) {
|
function tickFormatter(valIndex: string) {
|
||||||
let valueFormatted = tsBuckets[valIndex];
|
let valueFormatted = tsBuckets[valIndex];
|
||||||
if (!_.isNaN(_.toNumber(valueFormatted)) && valueFormatted !== '') {
|
if (!_.isNaN(_.toNumber(valueFormatted)) && valueFormatted !== '') {
|
||||||
// Try to format numeric tick labels
|
// Try to format numeric tick labels
|
||||||
@@ -393,7 +393,7 @@ export class HeatmapRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Adjust data range to log base
|
// Adjust data range to log base
|
||||||
adjustLogRange(min, max, logBase) {
|
adjustLogRange(min: number, max: number, logBase: number) {
|
||||||
let yMin = this.data.heatmapStats.minLog;
|
let yMin = this.data.heatmapStats.minLog;
|
||||||
if (this.data.heatmapStats.minLog > 1 || !this.data.heatmapStats.minLog) {
|
if (this.data.heatmapStats.minLog > 1 || !this.data.heatmapStats.minLog) {
|
||||||
yMin = 1;
|
yMin = 1;
|
||||||
@@ -407,15 +407,15 @@ export class HeatmapRenderer {
|
|||||||
return { yMin, yMax };
|
return { yMin, yMax };
|
||||||
}
|
}
|
||||||
|
|
||||||
adjustLogMax(max, base) {
|
adjustLogMax(max: number, base: number) {
|
||||||
return Math.pow(base, Math.ceil(ticksUtils.logp(max, base)));
|
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)));
|
return Math.pow(base, Math.floor(ticksUtils.logp(min, base)));
|
||||||
}
|
}
|
||||||
|
|
||||||
logScaleTickValues(domain, base) {
|
logScaleTickValues(domain: any[], base: number) {
|
||||||
const domainMin = domain[0];
|
const domainMin = domain[0];
|
||||||
const domainMax = domain[1];
|
const domainMax = domain[1];
|
||||||
const tickValues = [];
|
const tickValues = [];
|
||||||
@@ -437,9 +437,9 @@ export class HeatmapRenderer {
|
|||||||
return tickValues;
|
return tickValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
tickValueFormatter(decimals, scaledDecimals = null) {
|
tickValueFormatter(decimals: number, scaledDecimals: any = null) {
|
||||||
const format = this.panel.yAxis.format;
|
const format = this.panel.yAxis.format;
|
||||||
return value => {
|
return (value: any) => {
|
||||||
try {
|
try {
|
||||||
return format !== 'none' ? getValueFormat(format)(value, decimals, scaledDecimals) : value;
|
return format !== 'none' ? getValueFormat(format)(value, decimals, scaledDecimals) : value;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -555,17 +555,17 @@ export class HeatmapRenderer {
|
|||||||
|
|
||||||
const $cards = this.$heatmap.find('.heatmap-card');
|
const $cards = this.$heatmap.find('.heatmap-card');
|
||||||
$cards
|
$cards
|
||||||
.on('mouseenter', event => {
|
.on('mouseenter', (event: any) => {
|
||||||
this.tooltip.mouseOverBucket = true;
|
this.tooltip.mouseOverBucket = true;
|
||||||
this.highlightCard(event);
|
this.highlightCard(event);
|
||||||
})
|
})
|
||||||
.on('mouseleave', event => {
|
.on('mouseleave', (event: any) => {
|
||||||
this.tooltip.mouseOverBucket = false;
|
this.tooltip.mouseOverBucket = false;
|
||||||
this.resetCardHighLight(event);
|
this.resetCardHighLight(event);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
highlightCard(event) {
|
highlightCard(event: any) {
|
||||||
const color = d3.select(event.target).style('fill');
|
const color = d3.select(event.target).style('fill');
|
||||||
const highlightColor = d3.color(color).darker(2);
|
const highlightColor = d3.color(color).darker(2);
|
||||||
const strokeColor = d3.color(color).brighter(4);
|
const strokeColor = d3.color(color).brighter(4);
|
||||||
@@ -577,7 +577,7 @@ export class HeatmapRenderer {
|
|||||||
.style('stroke-width', 1);
|
.style('stroke-width', 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
resetCardHighLight(event) {
|
resetCardHighLight(event: any) {
|
||||||
d3.select(event.target)
|
d3.select(event.target)
|
||||||
.style('fill', this.tooltip.originalFillColor)
|
.style('fill', this.tooltip.originalFillColor)
|
||||||
.style('stroke', this.tooltip.originalFillColor)
|
.style('stroke', this.tooltip.originalFillColor)
|
||||||
@@ -599,7 +599,7 @@ export class HeatmapRenderer {
|
|||||||
this.cardHeight = yGridSize ? yGridSize - this.cardPadding * 2 : 0;
|
this.cardHeight = yGridSize ? yGridSize - this.cardPadding * 2 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
getCardX(d) {
|
getCardX(d: { x: any }) {
|
||||||
let x;
|
let x;
|
||||||
if (this.xScale(d.x) < 0) {
|
if (this.xScale(d.x) < 0) {
|
||||||
// Cut card left to prevent overlay
|
// Cut card left to prevent overlay
|
||||||
@@ -611,7 +611,7 @@ export class HeatmapRenderer {
|
|||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
getCardWidth(d) {
|
getCardWidth(d: { x: any }) {
|
||||||
let w = this.cardWidth;
|
let w = this.cardWidth;
|
||||||
if (this.xScale(d.x) < 0) {
|
if (this.xScale(d.x) < 0) {
|
||||||
// Cut card left to prevent overlay
|
// Cut card left to prevent overlay
|
||||||
@@ -626,7 +626,7 @@ export class HeatmapRenderer {
|
|||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
getCardY(d) {
|
getCardY(d: { y: number }) {
|
||||||
let y = this.yScale(d.y) + this.chartTop - this.cardHeight - this.cardPadding;
|
let y = this.yScale(d.y) + this.chartTop - this.cardHeight - this.cardPadding;
|
||||||
if (this.panel.yAxis.logBase !== 1 && d.y === 0) {
|
if (this.panel.yAxis.logBase !== 1 && d.y === 0) {
|
||||||
y = this.chartBottom - this.cardHeight - this.cardPadding;
|
y = this.chartBottom - this.cardHeight - this.cardPadding;
|
||||||
@@ -639,7 +639,7 @@ export class HeatmapRenderer {
|
|||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
getCardHeight(d) {
|
getCardHeight(d: { y: number }) {
|
||||||
const y = this.yScale(d.y) + this.chartTop - this.cardHeight - this.cardPadding;
|
const y = this.yScale(d.y) + this.chartTop - this.cardHeight - this.cardPadding;
|
||||||
let h = this.cardHeight;
|
let h = this.cardHeight;
|
||||||
|
|
||||||
@@ -664,7 +664,7 @@ export class HeatmapRenderer {
|
|||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
getCardColor(d) {
|
getCardColor(d: { count: any }) {
|
||||||
if (this.panel.color.mode === 'opacity') {
|
if (this.panel.color.mode === 'opacity') {
|
||||||
return getColorFromHexRgbOrName(
|
return getColorFromHexRgbOrName(
|
||||||
this.panel.color.cardColor,
|
this.panel.color.cardColor,
|
||||||
@@ -675,7 +675,7 @@ export class HeatmapRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getCardOpacity(d) {
|
getCardOpacity(d: { count: any }) {
|
||||||
if (this.panel.color.mode === 'opacity') {
|
if (this.panel.color.mode === 'opacity') {
|
||||||
return this.opacityScale(d.count);
|
return this.opacityScale(d.count);
|
||||||
} else {
|
} else {
|
||||||
@@ -683,14 +683,14 @@ export class HeatmapRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getEventOffset(event) {
|
getEventOffset(event: any) {
|
||||||
const elemOffset = this.$heatmap.offset();
|
const elemOffset = this.$heatmap.offset();
|
||||||
const x = Math.floor(event.clientX - elemOffset.left);
|
const x = Math.floor(event.clientX - elemOffset.left);
|
||||||
const y = Math.floor(event.clientY - elemOffset.top);
|
const y = Math.floor(event.clientY - elemOffset.top);
|
||||||
return { x, y };
|
return { x, y };
|
||||||
}
|
}
|
||||||
|
|
||||||
onMouseDown(event) {
|
onMouseDown(event: any) {
|
||||||
const offset = this.getEventOffset(event);
|
const offset = this.getEventOffset(event);
|
||||||
this.selection.active = true;
|
this.selection.active = true;
|
||||||
this.selection.x1 = offset.x;
|
this.selection.x1 = offset.x;
|
||||||
@@ -726,7 +726,7 @@ export class HeatmapRenderer {
|
|||||||
this.clearCrosshair();
|
this.clearCrosshair();
|
||||||
}
|
}
|
||||||
|
|
||||||
onMouseMove(event) {
|
onMouseMove(event: any) {
|
||||||
if (!this.heatmap) {
|
if (!this.heatmap) {
|
||||||
return;
|
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 x = this.xScale.invert(offset.x - this.yAxisWidth).valueOf();
|
||||||
const y = this.yScale.invert(offset.y - this.chartTop);
|
const y = this.yScale.invert(offset.y - this.chartTop);
|
||||||
const pos = {
|
const pos: any = {
|
||||||
pageX: event.pageX,
|
pageX: event.pageX,
|
||||||
pageY: event.pageY,
|
pageY: event.pageY,
|
||||||
x: x,
|
x: x,
|
||||||
@@ -764,20 +764,20 @@ export class HeatmapRenderer {
|
|||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
emitGraphHoverEvent(pos) {
|
emitGraphHoverEvent(pos: { panelRelY: number; offset: { y: number } }) {
|
||||||
// Set minimum offset to prevent showing legend from another panel
|
// Set minimum offset to prevent showing legend from another panel
|
||||||
pos.panelRelY = Math.max(pos.offset.y / this.height, 0.001);
|
pos.panelRelY = Math.max(pos.offset.y / this.height, 0.001);
|
||||||
// broadcast to other graph panels that we are hovering
|
// broadcast to other graph panels that we are hovering
|
||||||
appEvents.emit('graph-hover', { pos: pos, panel: this.panel });
|
appEvents.emit('graph-hover', { pos: pos, panel: this.panel });
|
||||||
}
|
}
|
||||||
|
|
||||||
limitSelection(x2) {
|
limitSelection(x2: number) {
|
||||||
x2 = Math.max(x2, this.yAxisWidth);
|
x2 = Math.max(x2, this.yAxisWidth);
|
||||||
x2 = Math.min(x2, this.chartWidth + this.yAxisWidth);
|
x2 = Math.min(x2, this.chartWidth + this.yAxisWidth);
|
||||||
return x2;
|
return x2;
|
||||||
}
|
}
|
||||||
|
|
||||||
drawSelection(posX1, posX2) {
|
drawSelection(posX1: number, posX2: number) {
|
||||||
if (this.heatmap) {
|
if (this.heatmap) {
|
||||||
this.heatmap.selectAll('.heatmap-selection').remove();
|
this.heatmap.selectAll('.heatmap-selection').remove();
|
||||||
const selectionX = Math.min(posX1, posX2);
|
const selectionX = Math.min(posX1, posX2);
|
||||||
@@ -804,7 +804,7 @@ export class HeatmapRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
drawCrosshair(position) {
|
drawCrosshair(position: number) {
|
||||||
if (this.heatmap) {
|
if (this.heatmap) {
|
||||||
this.heatmap.selectAll('.heatmap-crosshair').remove();
|
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) {
|
if (this.heatmap && this.ctrl.dashboard.graphTooltip !== 0) {
|
||||||
const posX = this.xScale(pos.x) + this.yAxisWidth;
|
const posX = this.xScale(pos.x) + this.yAxisWidth;
|
||||||
this.drawCrosshair(posX);
|
this.drawCrosshair(posX);
|
||||||
|
@@ -8,6 +8,7 @@ import {
|
|||||||
calculateBucketSize,
|
calculateBucketSize,
|
||||||
isHeatmapDataEqual,
|
isHeatmapDataEqual,
|
||||||
} from '../heatmap_data_converter';
|
} from '../heatmap_data_converter';
|
||||||
|
import { HeatmapData } from '../types';
|
||||||
|
|
||||||
describe('isHeatmapDataEqual', () => {
|
describe('isHeatmapDataEqual', () => {
|
||||||
const ctx: any = {};
|
const ctx: any = {};
|
||||||
@@ -248,7 +249,7 @@ describe('Histogram converter', () => {
|
|||||||
beforeEach(() => {});
|
beforeEach(() => {});
|
||||||
|
|
||||||
it('should build proper heatmap data', () => {
|
it('should build proper heatmap data', () => {
|
||||||
const expectedHeatmap = {
|
const expectedHeatmap: HeatmapData = {
|
||||||
'1422774000000': {
|
'1422774000000': {
|
||||||
x: 1422774000000,
|
x: 1422774000000,
|
||||||
buckets: {
|
buckets: {
|
||||||
@@ -322,7 +323,7 @@ describe('Histogram converter', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('convertToCards', () => {
|
describe('convertToCards', () => {
|
||||||
let buckets = {};
|
let buckets: HeatmapData = {};
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
buckets = {
|
buckets = {
|
||||||
|
42
public/app/plugins/panel/heatmap/types.ts
Normal file
42
public/app/plugins/panel/heatmap/types.ts
Normal file
@@ -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;
|
||||||
|
};
|
||||||
|
}
|
@@ -1,25 +1,27 @@
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { getValueFormat, getColorFromHexRgbOrName, GrafanaThemeType } from '@grafana/ui';
|
import { getValueFormat, getColorFromHexRgbOrName, GrafanaThemeType, ScopedVars } from '@grafana/ui';
|
||||||
import { stringToJsRegex } from '@grafana/data';
|
import { stringToJsRegex } from '@grafana/data';
|
||||||
import { ColumnStyle } from '@grafana/ui/src/components/Table/TableCellBuilder';
|
import { ColumnStyle } from '@grafana/ui/src/components/Table/TableCellBuilder';
|
||||||
import { dateTime } from '@grafana/ui/src/utils/moment_wrapper';
|
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 {
|
export class TableRenderer {
|
||||||
formatters: any[];
|
formatters: any[];
|
||||||
colorState: any;
|
colorState: any;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private panel,
|
private panel: { styles: ColumnStyle[]; pageSize: number },
|
||||||
private table,
|
private table: TableRenderModel,
|
||||||
private isUtc,
|
private isUtc: boolean,
|
||||||
private sanitize,
|
private sanitize: (v: any) => any,
|
||||||
private templateSrv,
|
private templateSrv: TemplateSrv,
|
||||||
private theme?: GrafanaThemeType
|
private theme?: GrafanaThemeType
|
||||||
) {
|
) {
|
||||||
this.initColumns();
|
this.initColumns();
|
||||||
}
|
}
|
||||||
|
|
||||||
setTable(table) {
|
setTable(table: TableRenderModel) {
|
||||||
this.table = table;
|
this.table = table;
|
||||||
|
|
||||||
this.initColumns();
|
this.initColumns();
|
||||||
@@ -52,7 +54,7 @@ export class TableRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getColorForValue(value, style: ColumnStyle) {
|
getColorForValue(value: number, style: ColumnStyle) {
|
||||||
if (!style.thresholds) {
|
if (!style.thresholds) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -64,7 +66,7 @@ export class TableRenderer {
|
|||||||
return getColorFromHexRgbOrName(_.first(style.colors), this.theme);
|
return getColorFromHexRgbOrName(_.first(style.colors), this.theme);
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultCellFormatter(v, style: ColumnStyle) {
|
defaultCellFormatter(v: any, style: ColumnStyle) {
|
||||||
if (v === null || v === void 0 || v === undefined) {
|
if (v === null || v === void 0 || v === undefined) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
@@ -80,19 +82,17 @@ export class TableRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
createColumnFormatter(column) {
|
createColumnFormatter(column: ColumnRender) {
|
||||||
if (!column.style) {
|
if (!column.style) {
|
||||||
return this.defaultCellFormatter;
|
return this.defaultCellFormatter;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (column.style.type === 'hidden') {
|
if (column.style.type === 'hidden') {
|
||||||
return v => {
|
return (v: any): undefined => undefined;
|
||||||
return undefined;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (column.style.type === 'date') {
|
if (column.style.type === 'date') {
|
||||||
return v => {
|
return (v: any) => {
|
||||||
if (v === undefined || v === null) {
|
if (v === undefined || v === null) {
|
||||||
return '-';
|
return '-';
|
||||||
}
|
}
|
||||||
@@ -117,7 +117,7 @@ export class TableRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (column.style.type === 'string') {
|
if (column.style.type === 'string') {
|
||||||
return v => {
|
return (v: any): any => {
|
||||||
if (_.isArray(v)) {
|
if (_.isArray(v)) {
|
||||||
v = v.join(', ');
|
v = v.join(', ');
|
||||||
}
|
}
|
||||||
@@ -173,7 +173,7 @@ export class TableRenderer {
|
|||||||
if (column.style.type === 'number') {
|
if (column.style.type === 'number') {
|
||||||
const valueFormatter = getValueFormat(column.unit || column.style.unit);
|
const valueFormatter = getValueFormat(column.unit || column.style.unit);
|
||||||
|
|
||||||
return v => {
|
return (v: any): any => {
|
||||||
if (v === null || v === void 0) {
|
if (v === null || v === void 0) {
|
||||||
return '-';
|
return '-';
|
||||||
}
|
}
|
||||||
@@ -187,12 +187,12 @@ export class TableRenderer {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return value => {
|
return (value: any) => {
|
||||||
return this.defaultCellFormatter(value, column.style);
|
return this.defaultCellFormatter(value, column.style);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
setColorState(value, style: ColumnStyle) {
|
setColorState(value: any, style: ColumnStyle) {
|
||||||
if (!style.colorMode) {
|
if (!style.colorMode) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -209,22 +209,22 @@ export class TableRenderer {
|
|||||||
this.colorState[style.colorMode] = this.getColorForValue(numericValue, style);
|
this.colorState[style.colorMode] = this.getColorForValue(numericValue, style);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderRowVariables(rowIndex) {
|
renderRowVariables(rowIndex: number) {
|
||||||
const scopedVars = {};
|
const scopedVars: ScopedVars = {};
|
||||||
let cellVariable;
|
let cellVariable;
|
||||||
const row = this.table.rows[rowIndex];
|
const row = this.table.rows[rowIndex];
|
||||||
for (let i = 0; i < row.length; i++) {
|
for (let i = 0; i < row.length; i++) {
|
||||||
cellVariable = `__cell_${i}`;
|
cellVariable = `__cell_${i}`;
|
||||||
scopedVars[cellVariable] = { value: row[i] };
|
scopedVars[cellVariable] = { value: row[i], text: row[i] ? row[i].toString() : '' };
|
||||||
}
|
}
|
||||||
return scopedVars;
|
return scopedVars;
|
||||||
}
|
}
|
||||||
|
|
||||||
formatColumnValue(colIndex, value) {
|
formatColumnValue(colIndex: number, value: any) {
|
||||||
return this.formatters[colIndex] ? this.formatters[colIndex](value) : value;
|
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);
|
value = this.formatColumnValue(columnIndex, value);
|
||||||
|
|
||||||
const column = this.table.columns[columnIndex];
|
const column = this.table.columns[columnIndex];
|
||||||
@@ -267,7 +267,7 @@ export class TableRenderer {
|
|||||||
if (column.style && column.style.link) {
|
if (column.style && column.style.link) {
|
||||||
// Render cell as link
|
// Render cell as link
|
||||||
const scopedVars = this.renderRowVariables(rowIndex);
|
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 cellLink = this.templateSrv.replace(column.style.linkUrl, scopedVars, encodeURIComponent);
|
||||||
const cellLinkTooltip = this.templateSrv.replace(column.style.linkTooltip, scopedVars);
|
const cellLinkTooltip = this.templateSrv.replace(column.style.linkTooltip, scopedVars);
|
||||||
@@ -305,7 +305,7 @@ export class TableRenderer {
|
|||||||
return columnHtml;
|
return columnHtml;
|
||||||
}
|
}
|
||||||
|
|
||||||
render(page) {
|
render(page: number) {
|
||||||
const pageSize = this.panel.pageSize || 100;
|
const pageSize = this.panel.pageSize || 100;
|
||||||
const startPos = page * pageSize;
|
const startPos = page * pageSize;
|
||||||
const endPos = Math.min(startPos + pageSize, this.table.rows.length);
|
const endPos = Math.min(startPos + pageSize, this.table.rows.length);
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import TableModel from 'app/core/table_model';
|
import TableModel from 'app/core/table_model';
|
||||||
import { TableRenderer } from '../renderer';
|
import { TableRenderer } from '../renderer';
|
||||||
import { getColorDefinitionByName } from '@grafana/ui';
|
import { getColorDefinitionByName, ScopedVars } from '@grafana/ui';
|
||||||
|
|
||||||
describe('when rendering table', () => {
|
describe('when rendering table', () => {
|
||||||
const SemiDarkOrange = getColorDefinitionByName('semi-dark-orange');
|
const SemiDarkOrange = getColorDefinitionByName('semi-dark-orange');
|
||||||
@@ -166,12 +166,12 @@ describe('when rendering table', () => {
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
const sanitize = value => {
|
const sanitize = (value: any): string => {
|
||||||
return 'sanitized';
|
return 'sanitized';
|
||||||
};
|
};
|
||||||
|
|
||||||
const templateSrv = {
|
const templateSrv = {
|
||||||
replace: (value, scopedVars) => {
|
replace: (value: any, scopedVars: ScopedVars) => {
|
||||||
if (scopedVars) {
|
if (scopedVars) {
|
||||||
// For testing variables replacement in link
|
// For testing variables replacement in link
|
||||||
_.each(scopedVars, (val, key) => {
|
_.each(scopedVars, (val, key) => {
|
||||||
@@ -182,6 +182,7 @@ describe('when rendering table', () => {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//@ts-ignore
|
||||||
const renderer = new TableRenderer(panel, table, 'utc', sanitize, templateSrv);
|
const renderer = new TableRenderer(panel, table, 'utc', sanitize, templateSrv);
|
||||||
|
|
||||||
it('time column should be formated', () => {
|
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();
|
return str.replace(/\s+/gm, ' ').trim();
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,20 @@
|
|||||||
import TableModel from 'app/core/table_model';
|
import TableModel from 'app/core/table_model';
|
||||||
|
import { Column } from '@grafana/ui';
|
||||||
|
import { ColumnStyle } from '@grafana/ui/src/components/Table/TableCellBuilder';
|
||||||
|
|
||||||
export interface TableTransform {
|
export interface TableTransform {
|
||||||
description: string;
|
description: string;
|
||||||
getColumns(data?: any): any[];
|
getColumns(data?: any): any[];
|
||||||
transform(data: any, panel: any, model: TableModel): void;
|
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[][];
|
||||||
|
}
|
||||||
|
@@ -19,7 +19,7 @@ export class TablePanelEditor extends PureComponent<PanelEditorProps<Options>> {
|
|||||||
this.props.onOptionsChange({ ...this.props.options, rotate: !this.props.options.rotate });
|
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 });
|
this.props.onOptionsChange({ ...this.props.options, fixedColumns: target.value });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -19,7 +19,7 @@ interface State {
|
|||||||
export class TextPanel extends PureComponent<Props, State> {
|
export class TextPanel extends PureComponent<Props, State> {
|
||||||
remarkable: Remarkable;
|
remarkable: Remarkable;
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props: Props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
|
@@ -25,17 +25,19 @@ import DashboardPage from '../features/dashboard/containers/DashboardPage';
|
|||||||
import PluginPage from '../features/plugins/PluginPage';
|
import PluginPage from '../features/plugins/PluginPage';
|
||||||
import AppRootPage from 'app/features/plugins/AppRootPage';
|
import AppRootPage from 'app/features/plugins/AppRootPage';
|
||||||
import config from 'app/core/config';
|
import config from 'app/core/config';
|
||||||
|
import { route, ILocationProvider } from 'angular';
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import { DashboardRouteInfo } from 'app/types';
|
import { DashboardRouteInfo } from 'app/types';
|
||||||
|
|
||||||
/** @ngInject */
|
/** @ngInject */
|
||||||
export function setupAngularRoutes($routeProvider, $locationProvider) {
|
export function setupAngularRoutes($routeProvider: route.IRouteProvider, $locationProvider: ILocationProvider) {
|
||||||
$locationProvider.html5Mode(true);
|
$locationProvider.html5Mode(true);
|
||||||
|
|
||||||
$routeProvider
|
$routeProvider
|
||||||
.when('/', {
|
.when('/', {
|
||||||
template: '<react-container />',
|
template: '<react-container />',
|
||||||
|
//@ts-ignore
|
||||||
pageClass: 'page-dashboard',
|
pageClass: 'page-dashboard',
|
||||||
routeInfo: DashboardRouteInfo.Home,
|
routeInfo: DashboardRouteInfo.Home,
|
||||||
reloadOnSearch: false,
|
reloadOnSearch: false,
|
||||||
|
@@ -1664,7 +1664,14 @@
|
|||||||
react-input-autosize "^2.2.1"
|
react-input-autosize "^2.2.1"
|
||||||
react-transition-group "^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"
|
version "1.6.54"
|
||||||
resolved "https://registry.yarnpkg.com/@types/angular/-/angular-1.6.54.tgz#f9d5a03e4da7b021a6dabe5d63e899ed4567a5bd"
|
resolved "https://registry.yarnpkg.com/@types/angular/-/angular-1.6.54.tgz#f9d5a03e4da7b021a6dabe5d63e899ed4567a5bd"
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user