mirror of
https://github.com/grafana/grafana.git
synced 2026-07-30 00:08:10 -05:00
Merge remote-tracking branch 'grafana/master' into alpha-react-virtualized-table
* grafana/master: Fixed type issues introduced by adding angular types Typescript noAny fixes, start of a long journey Updated code stats collection Updated path to new script POC on collecting metrics in ci process renamed default variables: s -> sm, m -> md, l -> lg removed gf-form-margin variable and replaced with space- variables where it was used heatmap: able to hide buckets with zero value #12080 s -> sm, m -> md, l -> lg heatmap: fix prometheus buckets sorting, closes #15637 s -> sm, m -> md, l -> lg removed headings-margin-bottom variable remove kbn test Added scopedVars argument in datasourceSrv.get in DataPanel Refactoring of multi-value datasource PR #15812 fixed minor misstake with dashboard padding removed -margin, replaced with new general variables added new space variables to margins in AddPanelWidget, add_data_source, dashboard_settings and sidemenu added new variables for spacing, set margins in _cards with new variables Make datasource variables multiselect and dashboard repeatable
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
"@babel/preset-react": "^7.0.0",
|
||||
"@babel/preset-typescript": "^7.1.0",
|
||||
"@rtsao/plugin-proposal-class-properties": "^7.0.1-patch.1",
|
||||
"@types/angular": "^1.6.6",
|
||||
"@types/chalk": "^2.2.0",
|
||||
"@types/classnames": "^2.2.6",
|
||||
"@types/commander": "^2.12.2",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
.form-field {
|
||||
margin-bottom: $gf-form-margin;
|
||||
margin-bottom: $space-xxs;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
@@ -30,7 +30,7 @@ const FONT_SCALE = 1;
|
||||
export class Gauge extends PureComponent<Props> {
|
||||
canvasElement: any;
|
||||
|
||||
static defaultProps = {
|
||||
static defaultProps: Partial<Props> = {
|
||||
maxValue: 100,
|
||||
valueMappings: [],
|
||||
minValue: 0,
|
||||
@@ -41,7 +41,6 @@ export class Gauge extends PureComponent<Props> {
|
||||
thresholds: [],
|
||||
unit: 'none',
|
||||
stat: 'avg',
|
||||
theme: GrafanaThemeType.Dark,
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
@@ -134,7 +133,7 @@ export class Gauge extends PureComponent<Props> {
|
||||
Math.min(dimension / 5, 100) * (formattedValue !== null ? this.getFontScale(formattedValue.length) : 1);
|
||||
const thresholdLabelFontSize = fontSize / 2.5;
|
||||
|
||||
const options = {
|
||||
const options: any = {
|
||||
series: {
|
||||
gauges: {
|
||||
gauge: {
|
||||
|
||||
@@ -3,7 +3,7 @@ $select-input-bg-disabled: $input-bg-disabled;
|
||||
|
||||
@mixin select-control() {
|
||||
width: 100%;
|
||||
margin-right: $gf-form-margin;
|
||||
margin-right: $space-xs;
|
||||
@include border-radius($input-border-radius-sm);
|
||||
background-color: $input-bg;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,13 @@ $enable-hover-media-query: false !default;
|
||||
// Control the default styling of most Bootstrap elements by modifying these
|
||||
// variables. Mostly focused on spacing.
|
||||
|
||||
$spacer: ${theme.spacing.m} !default;
|
||||
$space-xxs: ${theme.spacing.xxs} !default;
|
||||
$space-xs: ${theme.spacing.xs} !default;
|
||||
$space-sm: ${theme.spacing.sm} !default;
|
||||
$space-md: ${theme.spacing.md} !default;
|
||||
$space-lg: ${theme.spacing.lg} !default;
|
||||
$space-xl: ${theme.spacing.xl} !default;
|
||||
$spacer: ${theme.spacing.d} !default;
|
||||
$spacer-x: $spacer !default;
|
||||
$spacer-y: $spacer !default;
|
||||
$spacers: (
|
||||
@@ -46,7 +52,7 @@ $spacers: (
|
||||
),
|
||||
),
|
||||
) !default;
|
||||
$border-width: ${theme.border.width.s} !default;
|
||||
$border-width: ${theme.border.width.sm} !default;
|
||||
|
||||
// Grid breakpoints
|
||||
//
|
||||
@@ -55,9 +61,9 @@ $border-width: ${theme.border.width.s} !default;
|
||||
|
||||
$grid-breakpoints: (
|
||||
xs: ${theme.breakpoints.xs},
|
||||
sm: ${theme.breakpoints.s},
|
||||
md: ${theme.breakpoints.m},
|
||||
lg: ${theme.breakpoints.l},
|
||||
sm: ${theme.breakpoints.sm},
|
||||
md: ${theme.breakpoints.md},
|
||||
lg: ${theme.breakpoints.lg},
|
||||
xl: ${theme.breakpoints.xl},
|
||||
) !default;
|
||||
|
||||
@@ -91,12 +97,12 @@ $font-family-base: $font-family-sans-serif !default;
|
||||
$font-size-root: ${theme.typography.size.root} !default;
|
||||
$font-size-base: ${theme.typography.size.base} !default;
|
||||
|
||||
$font-size-lg: ${theme.typography.size.l} !default;
|
||||
$font-size-md: ${theme.typography.size.m} !default;
|
||||
$font-size-sm: ${theme.typography.size.s} !default;
|
||||
$font-size-lg: ${theme.typography.size.lg} !default;
|
||||
$font-size-md: ${theme.typography.size.md} !default;
|
||||
$font-size-sm: ${theme.typography.size.sm} !default;
|
||||
$font-size-xs: ${theme.typography.size.xs} !default;
|
||||
|
||||
$line-height-base: ${theme.typography.lineHeight.l} !default;
|
||||
$line-height-base: ${theme.typography.lineHeight.lg} !default;
|
||||
$font-weight-semi-bold: ${theme.typography.weight.semibold};
|
||||
|
||||
$font-size-h1: ${theme.typography.heading.h1} !default;
|
||||
@@ -106,10 +112,9 @@ $font-size-h4: ${theme.typography.heading.h4} !default;
|
||||
$font-size-h5: ${theme.typography.heading.h5} !default;
|
||||
$font-size-h6: ${theme.typography.heading.h6} !default;
|
||||
|
||||
$headings-margin-bottom: ($spacer / 2) !default;
|
||||
$headings-font-family: 'Roboto', 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
$headings-font-weight: ${theme.typography.weight.normal} !default;
|
||||
$headings-line-height: ${theme.typography.lineHeight.s} !default;
|
||||
$headings-line-height: ${theme.typography.lineHeight.sm} !default;
|
||||
|
||||
$hr-border-width: $border-width !default;
|
||||
$dt-font-weight: bold !default;
|
||||
@@ -160,7 +165,6 @@ $input-padding-y-lg: 10px !default;
|
||||
|
||||
$input-height: 35px !default;
|
||||
|
||||
$gf-form-margin: 3px;
|
||||
$gf-form-input-height: 35px;
|
||||
|
||||
$cursor-disabled: not-allowed !default;
|
||||
@@ -207,8 +211,7 @@ $btn-semi-transparent: rgba(0, 0, 0, 0.2) !default;
|
||||
$side-menu-width: 60px;
|
||||
|
||||
// dashboard
|
||||
$panel-margin: 10px;
|
||||
$dashboard-padding: $panel-margin * 2;
|
||||
$dashboard-padding: 10px * 2;
|
||||
$panel-horizontal-padding: 10;
|
||||
$panel-vertical-padding: 5;
|
||||
$panel-padding: 0px $panel-horizontal-padding + 0px $panel-vertical-padding + 0px $panel-horizontal-padding + 0px;
|
||||
|
||||
@@ -11,9 +11,9 @@ const theme: GrafanaThemeCommons = {
|
||||
root: '14px',
|
||||
base: '13px',
|
||||
xs: '10px',
|
||||
s: '12px',
|
||||
m: '14px',
|
||||
l: '18px',
|
||||
sm: '12px',
|
||||
md: '14px',
|
||||
lg: '18px',
|
||||
},
|
||||
heading: {
|
||||
h1: '28px',
|
||||
@@ -30,33 +30,36 @@ const theme: GrafanaThemeCommons = {
|
||||
},
|
||||
lineHeight: {
|
||||
xs: 1,
|
||||
s: 1.1,
|
||||
m: 4 / 3,
|
||||
l: 1.5,
|
||||
sm: 1.1,
|
||||
md: 4 / 3,
|
||||
lg: 1.5,
|
||||
},
|
||||
},
|
||||
breakpoints: {
|
||||
xs: '0',
|
||||
s: '544px',
|
||||
m: '768px',
|
||||
l: '992px',
|
||||
sm: '544px',
|
||||
md: '768px',
|
||||
lg: '992px',
|
||||
xl: '1200px',
|
||||
},
|
||||
spacing: {
|
||||
xs: '0',
|
||||
s: '3px',
|
||||
m: '14px',
|
||||
l: '21px',
|
||||
d: '14px',
|
||||
xxs: '2px',
|
||||
xs: '4px',
|
||||
sm: '8px',
|
||||
md: '16px',
|
||||
lg: '24px',
|
||||
xl: '32px',
|
||||
gutter: '30px',
|
||||
},
|
||||
border: {
|
||||
radius: {
|
||||
xs: '2px',
|
||||
s: '3px',
|
||||
m: '5px',
|
||||
sm: '3px',
|
||||
md: '5px',
|
||||
},
|
||||
width: {
|
||||
s: '1px',
|
||||
sm: '1px',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -8,9 +8,9 @@ export interface GrafanaThemeCommons {
|
||||
// TODO: not sure if should be a part of theme
|
||||
breakpoints: {
|
||||
xs: string;
|
||||
s: string;
|
||||
m: string;
|
||||
l: string;
|
||||
sm: string;
|
||||
md: string;
|
||||
lg: string;
|
||||
xl: string;
|
||||
};
|
||||
typography: {
|
||||
@@ -22,9 +22,9 @@ export interface GrafanaThemeCommons {
|
||||
root: string;
|
||||
base: string;
|
||||
xs: string;
|
||||
s: string;
|
||||
m: string;
|
||||
l: string;
|
||||
sm: string;
|
||||
md: string;
|
||||
lg: string;
|
||||
};
|
||||
weight: {
|
||||
light: number;
|
||||
@@ -33,9 +33,9 @@ export interface GrafanaThemeCommons {
|
||||
};
|
||||
lineHeight: {
|
||||
xs: number; //1
|
||||
s: number; //1.1
|
||||
m: number; // 4/3
|
||||
l: number; // 1.5
|
||||
sm: number; //1.1
|
||||
md: number; // 4/3
|
||||
lg: number; // 1.5
|
||||
};
|
||||
// TODO: Refactor to use size instead of custom defs
|
||||
heading: {
|
||||
@@ -48,20 +48,23 @@ export interface GrafanaThemeCommons {
|
||||
};
|
||||
};
|
||||
spacing: {
|
||||
d: string;
|
||||
xxs: string;
|
||||
xs: string;
|
||||
s: string;
|
||||
m: string;
|
||||
l: string;
|
||||
sm: string;
|
||||
md: string;
|
||||
lg: string;
|
||||
xl: string;
|
||||
gutter: string;
|
||||
};
|
||||
border: {
|
||||
radius: {
|
||||
xs: string;
|
||||
s: string;
|
||||
m: string;
|
||||
sm: string;
|
||||
md: string;
|
||||
};
|
||||
width: {
|
||||
s: string;
|
||||
sm: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -10,13 +10,13 @@ coreModule.directive('jsonTree', [
|
||||
startExpanded: '@',
|
||||
rootName: '@',
|
||||
},
|
||||
link: (scope, elem) => {
|
||||
link: (scope: any, elem) => {
|
||||
const jsonExp = new JsonExplorer(scope.object, 3, {
|
||||
animateOpen: true,
|
||||
});
|
||||
|
||||
const html = jsonExp.render(true);
|
||||
elem.html(html);
|
||||
elem.replaceAll(html);
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
@@ -14,7 +14,7 @@ coreModule.directive('giveFocus', () => {
|
||||
}
|
||||
setTimeout(() => {
|
||||
element.focus();
|
||||
const domEl = element[0];
|
||||
const domEl: any = element[0];
|
||||
if (domEl.setSelectionRange) {
|
||||
const pos = element.val().length * 2;
|
||||
domEl.setSelectionRange(pos, pos);
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
import kbn from '../utils/kbn';
|
||||
|
||||
describe('stringToJsRegex', () => {
|
||||
it('should parse the valid regex value', () => {
|
||||
const output = kbn.stringToJsRegex('/validRegexp/');
|
||||
expect(output).toBeInstanceOf(RegExp);
|
||||
});
|
||||
|
||||
it('should throw error on invalid regex value', () => {
|
||||
const input = '/etc/hostname';
|
||||
expect(() => {
|
||||
kbn.stringToJsRegex(input);
|
||||
}).toThrow();
|
||||
});
|
||||
});
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
.gicon {
|
||||
font-size: 30px;
|
||||
margin-right: $spacer;
|
||||
margin-right: $space-md;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@@ -32,16 +32,16 @@
|
||||
.add-panel-widget__title {
|
||||
font-size: $font-size-md;
|
||||
font-weight: $font-weight-semi-bold;
|
||||
margin-right: $spacer * 2;
|
||||
margin-right: $space-xl;
|
||||
}
|
||||
|
||||
.add-panel-widget__link {
|
||||
margin: 0 8px;
|
||||
margin: 0 $space-sm;
|
||||
width: 154px;
|
||||
}
|
||||
|
||||
.add-panel-widget__icon {
|
||||
margin-bottom: 8px;
|
||||
margin-bottom: $space-sm;
|
||||
|
||||
.gicon {
|
||||
color: white;
|
||||
@@ -62,7 +62,7 @@
|
||||
|
||||
.add-panel-widget__create {
|
||||
display: inherit;
|
||||
margin-bottom: 24px;
|
||||
margin-bottom: $space-lg;
|
||||
// this is to have the big button appear centered
|
||||
margin-top: 55px;
|
||||
}
|
||||
@@ -72,7 +72,7 @@
|
||||
}
|
||||
|
||||
.add-panel-widget__action {
|
||||
margin: 0 4px;
|
||||
margin: 0 $space-xs;
|
||||
}
|
||||
|
||||
.add-panel-widget__btn-container {
|
||||
|
||||
@@ -116,7 +116,7 @@ export class DataPanel extends Component<Props, State> {
|
||||
this.setState({ loading: LoadingState.Loading });
|
||||
|
||||
try {
|
||||
const ds = await this.dataSourceSrv.get(datasource);
|
||||
const ds = await this.dataSourceSrv.get(datasource, scopedVars);
|
||||
|
||||
// TODO interpolate variables
|
||||
const minInterval = this.props.minInterval || ds.interval;
|
||||
|
||||
@@ -9,7 +9,7 @@ coreModule.directive('datasourceHttpSettings', () => {
|
||||
},
|
||||
templateUrl: 'public/app/features/datasources/partials/http_settings.html',
|
||||
link: {
|
||||
pre: ($scope, elem, attrs) => {
|
||||
pre: ($scope: any, elem, attrs) => {
|
||||
// do not show access option if direct access is disabled
|
||||
$scope.showAccessOption = $scope.noDirectAccess !== 'true';
|
||||
$scope.showAccessHelp = false;
|
||||
|
||||
@@ -81,7 +81,7 @@ class MetricsPanelCtrl extends PanelCtrl {
|
||||
|
||||
// load datasource service
|
||||
this.datasourceSrv
|
||||
.get(this.panel.datasource)
|
||||
.get(this.panel.datasource, this.panel.scopedVars)
|
||||
.then(this.updateTimeRange.bind(this))
|
||||
.then(this.issueQueries.bind(this))
|
||||
.then(this.handleQueryResult.bind(this))
|
||||
|
||||
@@ -33,7 +33,7 @@ module.directive('grafanaPanel', ($rootScope, $document, $timeout) => {
|
||||
template: panelTemplate,
|
||||
transclude: true,
|
||||
scope: { ctrl: '=' },
|
||||
link: (scope, elem) => {
|
||||
link: (scope: any, elem) => {
|
||||
const panelContainer = elem.find('.panel-container');
|
||||
const panelContent = elem.find('.panel-content');
|
||||
const cornerInfoElem = elem.find('.panel-info-corner');
|
||||
@@ -67,7 +67,7 @@ module.directive('grafanaPanel', ($rootScope, $document, $timeout) => {
|
||||
// set initial transparency
|
||||
if (ctrl.panel.transparent) {
|
||||
transparentLastState = true;
|
||||
panelContainer.addClass('panel-transparent', true);
|
||||
panelContainer.addClass('panel-transparent');
|
||||
}
|
||||
|
||||
// update scrollbar after mounting
|
||||
|
||||
@@ -7,7 +7,7 @@ import config from 'app/core/config';
|
||||
import { importPluginModule } from './plugin_loader';
|
||||
|
||||
// Types
|
||||
import { DataSourceApi, DataSourceSelectItem } from '@grafana/ui/src/types';
|
||||
import { DataSourceApi, DataSourceSelectItem, ScopedVars } from '@grafana/ui/src/types';
|
||||
|
||||
export class DatasourceSrv {
|
||||
datasources: { [name: string]: DataSourceApi };
|
||||
@@ -21,12 +21,18 @@ export class DatasourceSrv {
|
||||
this.datasources = {};
|
||||
}
|
||||
|
||||
get(name?: string): Promise<DataSourceApi> {
|
||||
get(name?: string, scopedVars?: ScopedVars): Promise<DataSourceApi> {
|
||||
if (!name) {
|
||||
return this.get(config.defaultDatasource);
|
||||
}
|
||||
|
||||
name = this.templateSrv.replace(name);
|
||||
// Interpolation here is to support template variable in data source selection
|
||||
name = this.templateSrv.replace(name, scopedVars, (value, variable) => {
|
||||
if (Array.isArray(value)) {
|
||||
return value[0];
|
||||
}
|
||||
return value;
|
||||
});
|
||||
|
||||
if (name === 'default') {
|
||||
return this.get(config.defaultDatasource);
|
||||
|
||||
@@ -6,6 +6,8 @@ export class DatasourceVariable implements Variable {
|
||||
query: string;
|
||||
options: any;
|
||||
current: any;
|
||||
multi: boolean;
|
||||
includeAll: boolean;
|
||||
refresh: any;
|
||||
skipUrlSync: boolean;
|
||||
|
||||
@@ -18,6 +20,8 @@ export class DatasourceVariable implements Variable {
|
||||
regex: '',
|
||||
options: [],
|
||||
query: '',
|
||||
multi: false,
|
||||
includeAll: false,
|
||||
refresh: 1,
|
||||
skipUrlSync: false,
|
||||
};
|
||||
@@ -69,9 +73,16 @@ export class DatasourceVariable implements Variable {
|
||||
}
|
||||
|
||||
this.options = options;
|
||||
if (this.includeAll) {
|
||||
this.addAllOption();
|
||||
}
|
||||
return this.variableSrv.validateVariableSelectionState(this);
|
||||
}
|
||||
|
||||
addAllOption() {
|
||||
this.options.unshift({ text: 'All', value: '$__all' });
|
||||
}
|
||||
|
||||
dependsOn(variable) {
|
||||
if (this.regex) {
|
||||
return containsVariable(this.regex, variable.name);
|
||||
@@ -84,6 +95,9 @@ export class DatasourceVariable implements Variable {
|
||||
}
|
||||
|
||||
getValueForUrl() {
|
||||
if (this.current.text === 'All') {
|
||||
return 'All';
|
||||
}
|
||||
return this.current.value;
|
||||
}
|
||||
}
|
||||
@@ -91,5 +105,6 @@ export class DatasourceVariable implements Variable {
|
||||
variableTypes['datasource'] = {
|
||||
name: 'Datasource',
|
||||
ctor: DatasourceVariable,
|
||||
supportsMulti: true,
|
||||
description: 'Enabled you to dynamically switch the datasource for multiple panels',
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import _ from 'lodash';
|
||||
import TableModel from 'app/core/table_model';
|
||||
import { TimeSeries } from '@grafana/ui';
|
||||
|
||||
export class ResultTransformer {
|
||||
constructor(private templateSrv) {}
|
||||
@@ -18,10 +19,10 @@ export class ResultTransformer {
|
||||
];
|
||||
} else if (prometheusResult && options.format === 'heatmap') {
|
||||
let seriesList = [];
|
||||
prometheusResult.sort(sortSeriesByLabel);
|
||||
for (const metricData of prometheusResult) {
|
||||
seriesList.push(this.transformMetricData(metricData, options, options.start, options.end));
|
||||
}
|
||||
seriesList.sort(sortSeriesByLabel);
|
||||
seriesList = this.transformToHistogramOverTime(seriesList);
|
||||
return seriesList;
|
||||
} else if (prometheusResult) {
|
||||
@@ -197,13 +198,13 @@ export class ResultTransformer {
|
||||
}
|
||||
}
|
||||
|
||||
function sortSeriesByLabel(s1, s2): number {
|
||||
function sortSeriesByLabel(s1: TimeSeries, s2: TimeSeries): number {
|
||||
let le1, le2;
|
||||
|
||||
try {
|
||||
// fail if not integer. might happen with bad queries
|
||||
le1 = parseHistogramLabel(s1.metric.le);
|
||||
le2 = parseHistogramLabel(s2.metric.le);
|
||||
le1 = parseHistogramLabel(s1.target);
|
||||
le2 = parseHistogramLabel(s2.target);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
return 0;
|
||||
|
||||
@@ -2,28 +2,6 @@ import coreModule from 'app/core/core_module';
|
||||
import _ from 'lodash';
|
||||
import { FilterSegments, DefaultFilterValue } from './filter_segments';
|
||||
|
||||
export class StackdriverFilter {
|
||||
/** @ngInject */
|
||||
constructor() {
|
||||
return {
|
||||
templateUrl: 'public/app/plugins/datasource/stackdriver/partials/query.filter.html',
|
||||
controller: 'StackdriverFilterCtrl',
|
||||
controllerAs: 'ctrl',
|
||||
bindToController: true,
|
||||
restrict: 'E',
|
||||
scope: {
|
||||
labelData: '<',
|
||||
loading: '<',
|
||||
groupBys: '<',
|
||||
filters: '<',
|
||||
filtersChanged: '&',
|
||||
groupBysChanged: '&',
|
||||
hideGroupBys: '<',
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export class StackdriverFilterCtrl {
|
||||
defaultRemoveGroupByValue = '-- remove group by --';
|
||||
resourceTypeValue = 'resource.type';
|
||||
@@ -193,5 +171,24 @@ export class StackdriverFilterCtrl {
|
||||
}
|
||||
}
|
||||
|
||||
coreModule.directive('stackdriverFilter', StackdriverFilter);
|
||||
coreModule.controller('StackdriverFilterCtrl', StackdriverFilterCtrl);
|
||||
/** @ngInject */
|
||||
function stackdriverFilter() {
|
||||
return {
|
||||
templateUrl: 'public/app/plugins/datasource/stackdriver/partials/query.filter.html',
|
||||
controller: StackdriverFilterCtrl,
|
||||
controllerAs: 'ctrl',
|
||||
bindToController: true,
|
||||
restrict: 'E',
|
||||
scope: {
|
||||
labelData: '<',
|
||||
loading: '<',
|
||||
groupBys: '<',
|
||||
filters: '<',
|
||||
filtersChanged: '&',
|
||||
groupBysChanged: '&',
|
||||
hideGroupBys: '<',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
coreModule.directive('stackdriverFilter', stackdriverFilter);
|
||||
|
||||
@@ -19,7 +19,7 @@ coreModule.directive('colorLegend', () => {
|
||||
return {
|
||||
restrict: 'E',
|
||||
template: '<div class="heatmap-color-legend"><svg width="16.5rem" height="24px"></svg></div>',
|
||||
link: (scope, elem, attrs) => {
|
||||
link: (scope: any, elem, attrs) => {
|
||||
const ctrl = scope.ctrl;
|
||||
const panel = scope.ctrl.panel;
|
||||
|
||||
@@ -55,7 +55,7 @@ coreModule.directive('heatmapLegend', () => {
|
||||
return {
|
||||
restrict: 'E',
|
||||
template: `<div class="heatmap-color-legend"><svg width="${LEGEND_WIDTH_PX}px" height="${LEGEND_HEIGHT_PX}px"></svg></div>`,
|
||||
link: (scope, elem, attrs) => {
|
||||
link: (scope: any, elem, attrs) => {
|
||||
const ctrl = scope.ctrl;
|
||||
const panel = scope.ctrl.panel;
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ const panelDefaults = {
|
||||
showHistogram: false,
|
||||
},
|
||||
highlightCards: true,
|
||||
hideZeroBuckets: false,
|
||||
};
|
||||
|
||||
const colorModes = ['opacity', 'spectrum'];
|
||||
@@ -97,7 +98,7 @@ const colorSchemes = [
|
||||
{ name: 'YlOrRd', value: 'interpolateYlOrRd', invert: 'dark' },
|
||||
];
|
||||
|
||||
const dsSupportHistogramSort = ['prometheus', 'elasticsearch'];
|
||||
const dsSupportHistogramSort = ['elasticsearch'];
|
||||
|
||||
export class HeatmapCtrl extends MetricsPanelCtrl {
|
||||
static templateUrl = 'module.html';
|
||||
@@ -204,7 +205,7 @@ export class HeatmapCtrl extends MetricsPanelCtrl {
|
||||
yBucketSize = 1;
|
||||
}
|
||||
|
||||
const { cards, cardStats } = convertToCards(bucketsData);
|
||||
const { cards, cardStats } = convertToCards(bucketsData, this.panel.hideZeroBuckets);
|
||||
|
||||
this.data = {
|
||||
buckets: bucketsData,
|
||||
@@ -246,7 +247,7 @@ export class HeatmapCtrl extends MetricsPanelCtrl {
|
||||
// Always let yBucketSize=1 in 'tsbuckets' mode
|
||||
yBucketSize = 1;
|
||||
|
||||
const { cards, cardStats } = convertToCards(bucketsData);
|
||||
const { cards, cardStats } = convertToCards(bucketsData, this.panel.hideZeroBuckets);
|
||||
|
||||
this.data = {
|
||||
buckets: bucketsData,
|
||||
|
||||
@@ -93,25 +93,43 @@ 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
|
||||
* @return {Array} Array of "card" objects
|
||||
* @return {Object} Array of "card" objects and stats
|
||||
*/
|
||||
function convertToCards(buckets) {
|
||||
function convertToCards(buckets: any, hideZero = false): { cards: HeatmapCard[]; cardStats: HeatmapCardStats } {
|
||||
let min = 0,
|
||||
max = 0;
|
||||
const cards = [];
|
||||
const cards: HeatmapCard[] = [];
|
||||
_.forEach(buckets, xBucket => {
|
||||
_.forEach(xBucket.buckets, yBucket => {
|
||||
const card = {
|
||||
const card: HeatmapCard = {
|
||||
x: xBucket.x,
|
||||
y: yBucket.y,
|
||||
yBounds: yBucket.bounds,
|
||||
values: yBucket.values,
|
||||
count: yBucket.count,
|
||||
};
|
||||
cards.push(card);
|
||||
if (!hideZero || card.count !== 0) {
|
||||
cards.push(card);
|
||||
}
|
||||
|
||||
if (cards.length === 1) {
|
||||
min = yBucket.count;
|
||||
|
||||
@@ -63,6 +63,10 @@
|
||||
|
||||
<div class="section gf-form-group">
|
||||
<h5 class="section-heading">Buckets</h5>
|
||||
<gf-form-switch class="gf-form" label-class="width-8"
|
||||
label="Hide zero"
|
||||
checked="ctrl.panel.hideZeroBuckets" on-change="ctrl.render()">
|
||||
</gf-form-switch>
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label width-8">Space</label>
|
||||
<input type="number" class="gf-form-input width-5" placeholder="auto" data-placement="right" bs-tooltip="''" ng-model="ctrl.panel.cards.cardPadding" ng-change="ctrl.refresh()" ng-model-onblur>
|
||||
|
||||
@@ -20,6 +20,12 @@ $enable-hover-media-query: false !default;
|
||||
// Control the default styling of most Bootstrap elements by modifying these
|
||||
// variables. Mostly focused on spacing.
|
||||
|
||||
$space-xxs: 2px !default;
|
||||
$space-xs: 4px !default;
|
||||
$space-sm: 8px !default;
|
||||
$space-md: 16px !default;
|
||||
$space-lg: 24px !default;
|
||||
$space-xl: 32px !default;
|
||||
$spacer: 14px !default;
|
||||
$spacer-x: $spacer !default;
|
||||
$spacer-y: $spacer !default;
|
||||
@@ -109,7 +115,6 @@ $font-size-h4: 18px !default;
|
||||
$font-size-h5: 16px !default;
|
||||
$font-size-h6: 14px !default;
|
||||
|
||||
$headings-margin-bottom: ($spacer / 2) !default;
|
||||
$headings-font-family: 'Roboto', 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
$headings-font-weight: 400 !default;
|
||||
$headings-line-height: 1.1 !default;
|
||||
@@ -163,7 +168,6 @@ $input-padding-y-lg: 10px !default;
|
||||
|
||||
$input-height: 35px !default;
|
||||
|
||||
$gf-form-margin: 3px;
|
||||
$gf-form-input-height: 35px;
|
||||
|
||||
$cursor-disabled: not-allowed !default;
|
||||
@@ -210,8 +214,7 @@ $btn-semi-transparent: rgba(0, 0, 0, 0.2) !default;
|
||||
$side-menu-width: 60px;
|
||||
|
||||
// dashboard
|
||||
$panel-margin: 10px;
|
||||
$dashboard-padding: $panel-margin * 2;
|
||||
$dashboard-padding: 10px * 2;
|
||||
$panel-horizontal-padding: 10;
|
||||
$panel-vertical-padding: 5;
|
||||
$panel-padding: 0px $panel-horizontal-padding + 0px $panel-vertical-padding + 0px $panel-horizontal-padding + 0px;
|
||||
|
||||
@@ -109,7 +109,7 @@ h6,
|
||||
.h4,
|
||||
.h5,
|
||||
.h6 {
|
||||
margin-bottom: $headings-margin-bottom;
|
||||
margin-bottom: $space-sm;
|
||||
font-family: $headings-font-family;
|
||||
font-weight: $headings-font-weight;
|
||||
line-height: $headings-line-height;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
.add-data-source-header {
|
||||
margin-bottom: $spacer * 2;
|
||||
margin-bottom: $space-xl;
|
||||
padding-top: $spacer;
|
||||
text-align: center;
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
.add-data-source-search {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-bottom: $panel-margin * 2;
|
||||
margin-bottom: $space-lg;
|
||||
}
|
||||
|
||||
.add-data-source-grid {
|
||||
@@ -41,6 +41,6 @@
|
||||
}
|
||||
|
||||
.add-data-source-grid-item-logo {
|
||||
margin: 0 15px;
|
||||
margin: 0 $space-md;
|
||||
width: 55px;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
.alert {
|
||||
padding: 15px 20px;
|
||||
margin-bottom: $panel-margin / 2;
|
||||
margin-bottom: $space-xs;
|
||||
text-shadow: 0 2px 0 rgba(255, 255, 255, 0.5);
|
||||
background: $alert-error-bg;
|
||||
position: relative;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.layout-selector {
|
||||
@include clearfix();
|
||||
|
||||
margin-left: $spacer;
|
||||
margin-left: $space-md;
|
||||
text-align: right;
|
||||
|
||||
button {
|
||||
@@ -9,7 +9,7 @@
|
||||
color: $text-color-weak;
|
||||
box-shadow: $card-shadow;
|
||||
border: none;
|
||||
padding: 0.5rem;
|
||||
padding: $space-sm;
|
||||
line-height: 1;
|
||||
font-size: 130%;
|
||||
float: right;
|
||||
@@ -35,7 +35,7 @@
|
||||
}
|
||||
|
||||
.card-section {
|
||||
margin-bottom: $spacer * 2;
|
||||
margin-bottom: $space-xl;
|
||||
}
|
||||
|
||||
.card-list {
|
||||
@@ -50,7 +50,7 @@
|
||||
height: 100%;
|
||||
background: $card-background;
|
||||
box-shadow: $card-shadow;
|
||||
padding: 1rem;
|
||||
padding: $space-md;
|
||||
border-radius: 4px;
|
||||
|
||||
&:hover {
|
||||
@@ -58,7 +58,7 @@
|
||||
}
|
||||
|
||||
.label-tag {
|
||||
margin-left: 6px;
|
||||
margin-left: $space-sm;
|
||||
font-size: 11px;
|
||||
padding: 2px 6px;
|
||||
}
|
||||
@@ -80,15 +80,8 @@
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.card-item-cog {
|
||||
font-size: 130%;
|
||||
position: relative;
|
||||
top: 1rem;
|
||||
color: $text-muted;
|
||||
}
|
||||
|
||||
.card-item-header {
|
||||
margin-bottom: $spacer;
|
||||
margin-bottom: $space-md;
|
||||
}
|
||||
|
||||
.card-item-type {
|
||||
@@ -110,7 +103,7 @@
|
||||
}
|
||||
|
||||
.card-item-label {
|
||||
margin-left: 8px;
|
||||
margin-left: $space-sm;
|
||||
}
|
||||
|
||||
.card-item-sub-name {
|
||||
@@ -123,7 +116,7 @@
|
||||
.card-item-sub-name--header {
|
||||
color: $text-color-weak;
|
||||
text-transform: uppercase;
|
||||
margin-bottom: $spacer;
|
||||
margin-bottom: $space-md;
|
||||
font-size: $font-size-sm;
|
||||
font-weight: bold;
|
||||
}
|
||||
@@ -136,7 +129,7 @@
|
||||
.card-item-notice {
|
||||
font-size: $font-size-sm;
|
||||
display: inline-block;
|
||||
margin-left: $spacer;
|
||||
margin-left: $space-md;
|
||||
}
|
||||
|
||||
.card-item-header-action {
|
||||
@@ -145,7 +138,7 @@
|
||||
|
||||
.card-item-wrapper {
|
||||
width: 100%;
|
||||
padding: 0 1rem 1rem 0rem;
|
||||
padding: 0 $space-md $space-md 0;
|
||||
}
|
||||
|
||||
.card-item-wrapper--clickable {
|
||||
@@ -153,7 +146,7 @@
|
||||
}
|
||||
|
||||
.card-item-figure {
|
||||
margin: 0 $spacer $spacer 0;
|
||||
margin: 0 $space-md $space-md 0;
|
||||
height: 6rem;
|
||||
|
||||
img {
|
||||
@@ -195,7 +188,7 @@
|
||||
.card-item-wrapper {
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
margin-bottom: 3px;
|
||||
margin-bottom: $space-xs;
|
||||
}
|
||||
|
||||
.card-item-wrapper--clickable {
|
||||
@@ -212,9 +205,9 @@
|
||||
}
|
||||
|
||||
.card-item-figure {
|
||||
margin: 0 $spacer 0 0;
|
||||
margin: 0 $space-md 0 0;
|
||||
img {
|
||||
width: 3.5rem;
|
||||
width: 48px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
font-size: $font-size-h3;
|
||||
padding-right: 60px;
|
||||
white-space: nowrap;
|
||||
margin-bottom: $spacer;
|
||||
margin-bottom: $space-md;
|
||||
|
||||
i {
|
||||
font-size: 25px;
|
||||
@@ -53,7 +53,7 @@
|
||||
|
||||
.dashboard-settings__header {
|
||||
font-size: $font-size-h3;
|
||||
margin-bottom: $spacer * 2;
|
||||
margin-bottom: $space-xl;
|
||||
}
|
||||
|
||||
.dashboard-settings__subheader {
|
||||
@@ -89,13 +89,13 @@
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
flex-grow: 1;
|
||||
margin: $spacer * 3 $spacer * 2 0 0;
|
||||
margin: 40px $space-xl 0 0;
|
||||
|
||||
button {
|
||||
margin-bottom: 10px;
|
||||
margin-bottom: $space-sm;
|
||||
}
|
||||
}
|
||||
|
||||
.dashboard-settings__json-save-button {
|
||||
margin-top: $spacer;
|
||||
margin-top: $space-md;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
$gf-form-margin: 3px;
|
||||
$input-border: 1px solid $input-border-color;
|
||||
|
||||
.gf-form {
|
||||
margin-bottom: $gf-form-margin;
|
||||
margin-bottom: $space-xxs;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
@@ -33,7 +32,7 @@ $input-border: 1px solid $input-border-color;
|
||||
|
||||
.gf-form--has-input-icon {
|
||||
position: relative;
|
||||
margin-right: $gf-form-margin;
|
||||
margin-right: $space-xs;
|
||||
|
||||
.gf-form-input-icon {
|
||||
position: absolute;
|
||||
@@ -82,7 +81,7 @@ $input-border: 1px solid $input-border-color;
|
||||
align-content: flex-start;
|
||||
|
||||
.gf-form + .gf-form {
|
||||
margin-left: $gf-form-margin;
|
||||
margin-left: $space-xs;
|
||||
}
|
||||
|
||||
&--nowrap {
|
||||
@@ -147,14 +146,14 @@ $input-border: 1px solid $input-border-color;
|
||||
}
|
||||
|
||||
.gf-form-label + .gf-form-label {
|
||||
margin-right: $gf-form-margin;
|
||||
margin-right: $space-xs;
|
||||
}
|
||||
|
||||
.gf-form-pre {
|
||||
display: block;
|
||||
flex-grow: 1;
|
||||
margin: 0;
|
||||
margin-right: $gf-form-margin;
|
||||
margin-right: $space-xs;
|
||||
border: $input-btn-border-width solid transparent;
|
||||
border-left: none;
|
||||
@include border-radius($label-border-radius-sm);
|
||||
@@ -336,7 +335,7 @@ $input-border: 1px solid $input-border-color;
|
||||
|
||||
.gf-form-btn {
|
||||
padding: $input-padding-y $input-padding-x;
|
||||
margin-right: $gf-form-margin;
|
||||
margin-right: $space-xs;
|
||||
line-height: $input-line-height;
|
||||
font-size: $font-size-sm;
|
||||
|
||||
@@ -354,7 +353,7 @@ $input-border: 1px solid $input-border-color;
|
||||
}
|
||||
|
||||
.gf-form-dropdown-typeahead {
|
||||
margin-right: $gf-form-margin;
|
||||
//margin-right: $space-xs; ?
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
@@ -391,7 +390,7 @@ $input-border: 1px solid $input-border-color;
|
||||
}
|
||||
|
||||
&--header {
|
||||
margin-bottom: $gf-form-margin;
|
||||
margin-bottom: $space-xxs;
|
||||
}
|
||||
|
||||
&--no-padding {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
margin-bottom: 2rem;
|
||||
border-top: 3px solid $info-box-border-color;
|
||||
margin-bottom: $spacer;
|
||||
margin-right: $gf-form-margin;
|
||||
margin-right: $space-xs;
|
||||
box-shadow: $card-shadow;
|
||||
flex-grow: 1;
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
&__spinner {
|
||||
font-size: 32px;
|
||||
margin-bottom: $panel-margin;
|
||||
margin-bottom: $space-sm;
|
||||
}
|
||||
|
||||
&__text {
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
}
|
||||
|
||||
.panel-editor-container__editor {
|
||||
margin-top: $panel-margin * 2;
|
||||
margin-top: $space-lg;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex: 1 1 0;
|
||||
@@ -80,7 +80,7 @@
|
||||
}
|
||||
|
||||
.submenu-controls {
|
||||
padding: 0 $dashboard-padding $panel-margin $dashboard-padding;
|
||||
padding: 0 $dashboard-padding $space-sm $dashboard-padding;
|
||||
}
|
||||
|
||||
.panel-editor-container__panel {
|
||||
|
||||
@@ -6,7 +6,7 @@ $column-horizontal-spacing: 10px;
|
||||
padding: $panel-padding;
|
||||
padding-top: 10px;
|
||||
border-radius: $border-radius;
|
||||
margin: 2 * $panel-margin 0 $panel-margin;
|
||||
margin: $space-md 0 $space-sm;
|
||||
border: $panel-border;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@
|
||||
font-size: $font-size-sm;
|
||||
color: $text-color-weak;
|
||||
border-bottom: 1px solid $dropdownDividerBottom;
|
||||
margin-bottom: 0.25rem;
|
||||
margin-bottom: $space-xs;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ li.sidemenu-org-switcher {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
> i.fa.fa-random {
|
||||
margin-right: 4px;
|
||||
margin-right: $space-xs;
|
||||
top: 1px;
|
||||
}
|
||||
}
|
||||
@@ -283,8 +283,8 @@ li.sidemenu-org-switcher {
|
||||
position: unset;
|
||||
width: 100%;
|
||||
float: none;
|
||||
margin-top: 0.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
margin-top: $space-sm;
|
||||
margin-bottom: $space-sm;
|
||||
|
||||
> li > a {
|
||||
padding-left: 15px;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
flex-wrap: wrap;
|
||||
align-content: flex-start;
|
||||
align-items: flex-start;
|
||||
padding: 0 0 $panel-margin 0;
|
||||
padding: 0 0 $space-sm 0;
|
||||
}
|
||||
|
||||
.annotation-disabled,
|
||||
|
||||
@@ -65,6 +65,11 @@
|
||||
font-size: 18px;
|
||||
min-height: 55px;
|
||||
line-height: 55px;
|
||||
justify-content: space-between;
|
||||
margin-left: $space-xl;
|
||||
}
|
||||
|
||||
.explore-toolbar-header {
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
@@ -163,7 +168,7 @@
|
||||
}
|
||||
|
||||
.explore-panel {
|
||||
margin-top: $panel-margin;
|
||||
margin-top: $space-sm;
|
||||
}
|
||||
|
||||
.explore-panel__body {
|
||||
@@ -182,24 +187,20 @@
|
||||
|
||||
.explore-panel__header-label {
|
||||
font-weight: 500;
|
||||
margin-right: $panel-margin;
|
||||
margin-right: $space-sm;
|
||||
font-size: $font-size-h6;
|
||||
box-shadow: $text-shadow-faint;
|
||||
}
|
||||
|
||||
.explore-panel__header-buttons {
|
||||
margin-right: $panel-margin;
|
||||
margin-right: $space-sm;
|
||||
font-size: $font-size-lg;
|
||||
line-height: $font-size-h6;
|
||||
}
|
||||
|
||||
.result-options {
|
||||
margin: 2 * $panel-margin 0;
|
||||
}
|
||||
|
||||
.time-series-disclaimer {
|
||||
width: 300px;
|
||||
margin: $panel-margin auto;
|
||||
margin: $space-sm auto;
|
||||
padding: 10px 0;
|
||||
border-radius: $border-radius;
|
||||
text-align: center;
|
||||
@@ -207,7 +208,7 @@
|
||||
|
||||
.disclaimer-icon {
|
||||
color: $yellow;
|
||||
margin-right: $panel-margin/2;
|
||||
margin-right: $space-xs;
|
||||
}
|
||||
|
||||
.show-all-time-series {
|
||||
@@ -234,7 +235,7 @@
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background: none;
|
||||
margin: $panel-margin / 2;
|
||||
margin: $space-xs;
|
||||
}
|
||||
|
||||
.explore-panel__loader--active:after {
|
||||
@@ -377,7 +378,7 @@
|
||||
.ReactTable .-pagination {
|
||||
border-top: none;
|
||||
box-shadow: none;
|
||||
margin-top: $panel-margin;
|
||||
margin-top: $space-sm;
|
||||
}
|
||||
.ReactTable .-pagination .-btn {
|
||||
color: $blue;
|
||||
@@ -418,7 +419,7 @@
|
||||
// TODO Experimental
|
||||
|
||||
.cheat-sheet-item {
|
||||
margin: 2 * $panel-margin 0;
|
||||
margin: $space-lg 0;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
@@ -427,6 +428,6 @@
|
||||
}
|
||||
|
||||
.cheat-sheet-item__expression {
|
||||
margin: $panel-margin/2 0;
|
||||
margin: $space-xs 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@@ -8,20 +8,20 @@
|
||||
// widths
|
||||
@for $i from 1 through 30 {
|
||||
.width-#{$i} {
|
||||
width: ($spacer * $i) - $gf-form-margin !important;
|
||||
width: ($spacer * $i) - $space-xs !important;
|
||||
}
|
||||
}
|
||||
|
||||
@for $i from 1 through 30 {
|
||||
.max-width-#{$i} {
|
||||
max-width: ($spacer * $i) - $gf-form-margin !important;
|
||||
max-width: ($spacer * $i) - $space-xs !important;
|
||||
flex-grow: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@for $i from 1 through 30 {
|
||||
.min-width-#{$i} {
|
||||
min-width: ($spacer * $i) - $gf-form-margin !important;
|
||||
min-width: ($spacer * $i) - $space-xs !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "Collecting code stats (typescript errors & more)"
|
||||
|
||||
ERROR_COUNT="$(./node_modules/.bin/tsc --project tsconfig.json --noEmit --noImplicitAny true | grep -oP 'Found \K(\d+)')"
|
||||
DIRECTIVES="$(grep -r -o directive public/app/**/* | wc -l)"
|
||||
CONTROLLERS="$(grep -r -oP 'class .*Ctrl' public/app/**/* | wc -l)"
|
||||
|
||||
echo "Typescript errors: $ERROR_COUNT"
|
||||
echo "Directives: $DIRECTIVES"
|
||||
echo "Controllers: $CONTROLLERS"
|
||||
|
||||
curl \
|
||||
-d "{\"metrics\": {
|
||||
\"ci.code.noImplicitAny\": $ERROR_COUNT,
|
||||
\"ci.code.directives\": $DIRECTIVES,
|
||||
\"ci.code.controllers\": $CONTROLLERS
|
||||
}
|
||||
}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-u ci:$CIRCLE_STATS_PWD \
|
||||
-X POST https://stats.grafana.org/metric-receiver
|
||||
|
||||
@@ -12,3 +12,9 @@ function exit_if_fail {
|
||||
|
||||
exit_if_fail npm run prettier:check
|
||||
exit_if_fail npm run test
|
||||
|
||||
# On master also collect some and send some metrics
|
||||
branch="$(git rev-parse --abbrev-ref HEAD)"
|
||||
if [ "${branch}" == "master" ]; then
|
||||
exit_if_fail ./scripts/circle-metrics.sh
|
||||
fi
|
||||
|
||||
@@ -1514,6 +1514,11 @@
|
||||
react-input-autosize "^2.2.1"
|
||||
react-transition-group "^2.2.1"
|
||||
|
||||
"@types/angular@^1.6.6":
|
||||
version "1.6.54"
|
||||
resolved "https://registry.yarnpkg.com/@types/angular/-/angular-1.6.54.tgz#f9d5a03e4da7b021a6dabe5d63e899ed4567a5bd"
|
||||
integrity sha512-xA1FuozWXeRQ7FClUbvk8ePL+dydBeDoCWRPFTHU5+8uvVtIIfLGiHA8CMkwsbddFCYnTDVbLxG85a/HBx7LtA==
|
||||
|
||||
"@types/chalk@^2.2.0":
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/chalk/-/chalk-2.2.0.tgz#b7f6e446f4511029ee8e3f43075fb5b73fbaa0ba"
|
||||
|
||||
Reference in New Issue
Block a user