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:
ryan
2019-03-12 09:04:20 -07:00
41 changed files with 256 additions and 190 deletions
+1
View File
@@ -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;
+19 -16
View File
@@ -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',
},
},
};
+18 -15
View File
@@ -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);
},
};
},
+1 -1
View File
@@ -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);
-15
View File
@@ -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))
+2 -2
View File
@@ -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>
+7 -4
View File
@@ -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;
+1 -1
View File
@@ -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;
+3 -3
View File
@@ -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;
}
+1 -1
View File
@@ -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;
+14 -21
View File
@@ -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;
}
+8 -9
View File
@@ -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 {
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -7,7 +7,7 @@
&__spinner {
font-size: 32px;
margin-bottom: $panel-margin;
margin-bottom: $space-sm;
}
&__text {
+2 -2
View File
@@ -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 {
+1 -1
View File
@@ -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;
}
+4 -4
View File
@@ -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;
+1 -1
View File
@@ -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,
+14 -13
View File
@@ -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;
}
+3 -3
View File
@@ -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;
}
}
+23
View File
@@ -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
+6
View File
@@ -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
+5
View File
@@ -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"