Chore: No implict any fixes (#17020)

pull/17027/head
Torkel Ödegaard 6 years ago committed by GitHub
parent 2fff8f77dc
commit e0b760e08e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      package.json
  2. 6
      packages/grafana-ui/src/types/datasource.ts
  3. 2
      public/app/core/components/PasswordStrength.tsx
  4. 2
      public/app/core/components/TagFilter/TagBadge.tsx
  5. 24
      public/app/core/components/TagFilter/TagFilter.tsx
  6. 2
      public/app/core/components/TagFilter/TagOption.tsx
  7. 5
      public/app/core/components/TagFilter/TagValue.tsx
  8. 4
      public/app/core/components/ToggleButtonGroup/ToggleButtonGroup.tsx
  9. 3
      public/app/core/components/dashboard_selector.ts
  10. 5
      public/app/core/components/info_popover.ts
  11. 7
      public/app/core/components/org_switcher.ts
  12. 2
      public/app/core/components/sql_part/sql_part.ts
  13. 26
      public/app/core/components/sql_part/sql_part_editor.ts
  14. 2
      public/app/core/components/switch.ts
  15. 2
      public/app/core/jquery_extended.ts
  16. 10
      public/app/core/logs_model.ts
  17. 2
      public/app/core/nav_model_srv.ts
  18. 2
      public/app/core/partials.ts
  19. 4
      public/app/core/profiler.ts
  20. 2
      public/app/core/services/backend_srv.ts
  21. 84
      public/app/core/services/segment_srv.ts
  22. 23
      public/app/core/table_model.ts
  23. 20
      public/app/core/time_series2.ts
  24. 2
      public/app/core/utils/connectWithReduxStore.tsx
  25. 19
      public/app/features/admin/AdminEditOrgCtrl.ts
  26. 24
      public/app/features/admin/AdminEditUserCtrl.ts
  27. 11
      public/app/features/admin/AdminListOrgsCtrl.ts
  28. 15
      public/app/features/admin/AdminListUsersCtrl.ts
  29. 1
      public/app/features/admin/ServerStats.test.tsx
  30. 6
      public/app/features/admin/StyleGuideCtrl.ts
  31. 12
      public/app/features/admin/index.ts
  32. 2
      public/app/features/alerting/AlertRuleItem.test.tsx
  33. 1
      public/app/features/alerting/AlertRuleItem.tsx
  34. 65
      public/app/features/alerting/AlertTabCtrl.ts
  35. 31
      public/app/features/alerting/NotificationsEditCtrl.ts
  36. 13
      public/app/features/alerting/NotificationsListCtrl.ts
  37. 6
      public/app/features/alerting/StateHistory.tsx
  38. 6
      public/app/features/alerting/state/ThresholdMapper.ts
  39. 8
      public/app/features/alerting/state/alertDef.ts
  40. 4
      public/app/features/alerting/state/reducers.test.ts
  41. 18
      public/app/features/alerting/state/reducers.ts
  42. 6
      public/app/features/alerting/state/selectors.test.ts
  43. 6
      public/app/features/alerting/state/selectors.ts
  44. 2
      public/app/features/dashboard/dashgrid/PanelChrome.tsx
  45. 2
      public/app/features/explore/Explore.tsx
  46. 21
      public/app/features/explore/QueryRow.tsx
  47. 1
      public/app/features/explore/Wrapper.tsx
  48. 9
      public/app/features/org/state/actions.ts
  49. 2
      public/app/features/panel/panel_ctrl.ts
  50. 2
      public/app/plugins/datasource/prometheus/datasource.ts
  51. 4
      public/app/types/alerting.ts
  52. 2
      scripts/ci-frontend-metrics.sh
  53. 19
      yarn.lock

@ -187,6 +187,7 @@
"dependencies": {
"@babel/polyfill": "7.2.5",
"@torkelo/react-select": "2.4.1",
"@types/react-redux": "^7.0.8",
"@types/reselect": "2.2.0",
"angular": "1.6.6",
"angular-bindonce": "0.3.1",
@ -201,8 +202,8 @@
"d3": "4.13.0",
"d3-scale-chromatic": "1.3.3",
"eventemitter3": "2.0.3",
"file-saver": "1.3.8",
"fast-text-encoding": "^1.0.0",
"file-saver": "1.3.8",
"immutable": "3.8.2",
"jquery": "3.4.0",
"lodash": "4.17.11",

@ -78,6 +78,7 @@ export interface DataSourcePluginMeta extends PluginMeta {
logs?: boolean;
explore?: boolean;
annotations?: boolean;
alerting?: boolean;
mixed?: boolean;
hasQueryHelp?: boolean;
category?: string;
@ -181,6 +182,11 @@ export abstract class DataSourceApi<
* static information about the datasource
*/
meta?: DataSourcePluginMeta;
/**
* Used by alerting to check if query contains template variables
*/
targetContainsTemplate?(query: TQuery): boolean;
}
export abstract class ExploreDataSourceApi<

@ -5,7 +5,7 @@ export interface Props {
}
export class PasswordStrength extends React.Component<Props, any> {
constructor(props) {
constructor(props: Props) {
super(props);
}

@ -9,7 +9,7 @@ export interface Props {
}
export class TagBadge extends React.Component<Props, any> {
constructor(props) {
constructor(props: Props) {
super(props);
}

@ -1,10 +1,14 @@
// Libraries
import React from 'react';
import { NoOptionsMessage, IndicatorsContainer, resetSelectStyles } from '@grafana/ui';
// @ts-ignore
import { components } from '@torkelo/react-select';
// @ts-ignore
import AsyncSelect from '@torkelo/react-select/lib/Async';
// Components
import { TagOption } from './TagOption';
import { TagBadge } from './TagBadge';
import { components } from '@torkelo/react-select';
import { NoOptionsMessage, IndicatorsContainer, resetSelectStyles } from '@grafana/ui';
import { escapeStringForRegex } from '../FilterInput/FilterInput';
export interface Props {
@ -16,12 +20,12 @@ export interface Props {
export class TagFilter extends React.Component<Props, any> {
inlineTags: boolean;
constructor(props) {
constructor(props: Props) {
super(props);
}
onLoadOptions = query => {
return this.props.tagOptions().then(options => {
onLoadOptions = (query: string) => {
return this.props.tagOptions().then((options: any[]) => {
return options.map(option => ({
value: option.term,
label: option.term,
@ -47,11 +51,11 @@ export class TagFilter extends React.Component<Props, any> {
placeholder: 'Tags',
loadingMessage: () => 'Loading...',
noOptionsMessage: () => 'No tags found',
getOptionValue: i => i.value,
getOptionLabel: i => i.label,
getOptionValue: (i: any) => i.value,
getOptionLabel: (i: any) => i.label,
value: tags,
styles: resetSelectStyles(),
filterOption: (option, searchQuery) => {
filterOption: (option: any, searchQuery: string) => {
const regex = RegExp(escapeStringForRegex(searchQuery), 'i');
return regex.test(option.value);
},
@ -59,10 +63,10 @@ export class TagFilter extends React.Component<Props, any> {
Option: TagOption,
IndicatorsContainer,
NoOptionsMessage,
MultiValueLabel: () => {
MultiValueLabel: (): any => {
return null; // We want the whole tag to be clickable so we use MultiValueRemove instead
},
MultiValueRemove: props => {
MultiValueRemove: (props: any) => {
const { data } = props;
return (

@ -1,4 +1,6 @@
// Libraries
import React from 'react';
// @ts-ignore
import { components } from '@torkelo/react-select';
import { OptionProps } from 'react-select/lib/components/Option';
import { TagBadge } from './TagBadge';

@ -9,18 +9,17 @@ export interface Props {
}
export class TagValue extends React.Component<Props, any> {
constructor(props) {
constructor(props: Props) {
super(props);
this.onClick = this.onClick.bind(this);
}
onClick(event) {
onClick(event: React.SyntheticEvent) {
this.props.onRemove(this.props.value, event);
}
render() {
const { value } = this.props;
return <TagBadge label={value.label} removeIcon={false} count={0} onClick={this.onClick} />;
}
}

@ -21,7 +21,7 @@ export default class ToggleButtonGroup extends PureComponent<ToggleButtonGroupPr
}
interface ToggleButtonProps {
onChange?: (value) => void;
onChange?: (value: any) => void;
selected?: boolean;
value: any;
className?: string;
@ -37,7 +37,7 @@ export const ToggleButton: FC<ToggleButtonProps> = ({
tooltip,
onChange,
}) => {
const onClick = event => {
const onClick = (event: React.SyntheticEvent) => {
event.stopPropagation();
if (onChange) {
onChange(value);

@ -1,4 +1,5 @@
import coreModule from 'app/core/core_module';
import { BackendSrv } from '../services/backend_srv';
const template = `
<select class="gf-form-input" ng-model="ctrl.model" ng-options="f.value as f.text for f in ctrl.options"></select>
@ -9,7 +10,7 @@ export class DashboardSelectorCtrl {
options: any;
/** @ngInject */
constructor(private backendSrv) {}
constructor(private backendSrv: BackendSrv) {}
$onInit() {
this.options = [{ value: 0, text: 'Default' }];

@ -1,5 +1,6 @@
import _ from 'lodash';
import coreModule from 'app/core/core_module';
// @ts-ignore
import Drop from 'tether-drop';
export function infoPopover() {
@ -7,7 +8,7 @@ export function infoPopover() {
restrict: 'E',
template: '<i class="fa fa-info-circle"></i>',
transclude: true,
link: (scope, elem, attrs, ctrl, transclude) => {
link: (scope: any, elem: any, attrs: any, transclude: any) => {
const offset = attrs.offset || '0 -10px';
const position = attrs.position || 'right middle';
let classes = 'drop-help drop-hide-out-of-bounds';
@ -23,7 +24,7 @@ export function infoPopover() {
elem.addClass('gf-form-help-icon--' + attrs.mode);
}
transclude((clone, newScope) => {
transclude((clone: any, newScope: any) => {
const content = document.createElement('div');
content.className = 'markdown-html';

@ -1,6 +1,7 @@
import coreModule from 'app/core/core_module';
import { contextSrv } from 'app/core/services/context_srv';
import config from 'app/core/config';
import { BackendSrv } from '../services/backend_srv';
const template = `
<div class="modal-body">
@ -47,18 +48,18 @@ export class OrgSwitchCtrl {
currentOrgId: any;
/** @ngInject */
constructor(private backendSrv) {
constructor(private backendSrv: BackendSrv) {
this.currentOrgId = contextSrv.user.orgId;
this.getUserOrgs();
}
getUserOrgs() {
this.backendSrv.get('/api/user/orgs').then(orgs => {
this.backendSrv.get('/api/user/orgs').then((orgs: any) => {
this.orgs = orgs;
});
}
setUsingOrg(org) {
setUsingOrg(org: any) {
return this.backendSrv.post('/api/user/using/' + org.orgId).then(() => {
this.setWindowLocation(config.appSubUrl + (config.appSubUrl.endsWith('/') ? '' : '/') + '?orgId=' + org.orgId);
});

@ -61,7 +61,7 @@ export class SqlPart {
this.params = part.params;
}
updateParam(strValue, index) {
updateParam(strValue: string, index: number) {
// handle optional parameters
if (strValue === '' && this.def.params[index].optional) {
this.params.splice(index, 1);

@ -14,7 +14,7 @@ const template = `
`;
/** @ngInject */
export function sqlPartEditorDirective($compile, templateSrv) {
export function sqlPartEditorDirective(templateSrv: any) {
const paramTemplate = '<input type="text" class="hide input-mini"></input>';
return {
@ -25,16 +25,16 @@ export function sqlPartEditorDirective($compile, templateSrv) {
handleEvent: '&',
debounce: '@',
},
link: function postLink($scope, elem) {
link: function postLink($scope: any, elem: any) {
const part = $scope.part;
const partDef = part.def;
const $paramsContainer = elem.find('.query-part-parameters');
const debounceLookup = $scope.debounce;
let cancelBlur = null;
let cancelBlur: any = null;
$scope.partActions = [];
function clickFuncParam(this: any, paramIndex) {
function clickFuncParam(this: any, paramIndex: number) {
/*jshint validthis:true */
const $link = $(this);
const $input = $link.next();
@ -54,13 +54,13 @@ export function sqlPartEditorDirective($compile, templateSrv) {
}
}
function inputBlur($input, paramIndex) {
function inputBlur($input: JQuery, paramIndex: number) {
cancelBlur = setTimeout(() => {
switchToLink($input, paramIndex);
}, 200);
}
function switchToLink($input, paramIndex) {
function switchToLink($input: JQuery, paramIndex: number) {
/*jshint validthis:true */
const $link = $input.prev();
const newValue = $input.val();
@ -78,7 +78,7 @@ export function sqlPartEditorDirective($compile, templateSrv) {
$link.show();
}
function inputKeyPress(this: any, paramIndex, e) {
function inputKeyPress(this: any, paramIndex: number, e: any) {
/*jshint validthis:true */
if (e.which === 13) {
switchToLink($(this), paramIndex);
@ -90,12 +90,12 @@ export function sqlPartEditorDirective($compile, templateSrv) {
this.style.width = (3 + this.value.length) * 8 + 'px';
}
function addTypeahead($input, param, paramIndex) {
function addTypeahead($input: JQuery, param: any, paramIndex: number) {
if (!param.options && !param.dynamicLookup) {
return;
}
const typeaheadSource = (query, callback) => {
const typeaheadSource = (query: string, callback: any) => {
if (param.options) {
let options = param.options;
if (param.type === 'int') {
@ -107,7 +107,7 @@ export function sqlPartEditorDirective($compile, templateSrv) {
}
$scope.$apply(() => {
$scope.handleEvent({ $event: { name: 'get-param-options', param: param } }).then(result => {
$scope.handleEvent({ $event: { name: 'get-param-options', param: param } }).then((result: any) => {
const dynamicOptions = _.map(result, op => {
return _.escape(op.value);
});
@ -128,7 +128,7 @@ export function sqlPartEditorDirective($compile, templateSrv) {
source: typeaheadSource,
minLength: 0,
items: 1000,
updater: value => {
updater: (value: string) => {
value = _.unescape(value);
if (value === part.params[paramIndex]) {
clearTimeout(cancelBlur);
@ -152,12 +152,12 @@ export function sqlPartEditorDirective($compile, templateSrv) {
}
$scope.showActionsMenu = () => {
$scope.handleEvent({ $event: { name: 'get-part-actions' } }).then(res => {
$scope.handleEvent({ $event: { name: 'get-part-actions' } }).then((res: any) => {
$scope.partActions = res;
});
};
$scope.triggerPartAction = action => {
$scope.triggerPartAction = (action: string) => {
$scope.handleEvent({ $event: { name: 'action', action: action } });
};

@ -38,7 +38,7 @@ export class SwitchCtrl {
label: string;
/** @ngInject */
constructor($scope, private $timeout) {
constructor($scope: any, private $timeout: any) {
this.show = true;
this.id = $scope.$id;
}

@ -9,7 +9,7 @@ $.fn.place_tt = (() => {
offset: 5,
};
return function(this: any, x, y, opts) {
return function(this: any, x: number, y: number, opts: any) {
opts = $.extend(true, {}, defaults, opts);
return this.each(() => {

@ -123,7 +123,7 @@ export const LogsParsers: { [name: string]: LogsParser } = {
JSON: {
buildMatcher: label => new RegExp(`(?:{|,)\\s*"${label}"\\s*:\\s*"?([\\d\\.]+|[^"]*)"?`),
getFields: line => {
const fields = [];
const fields: string[] = [];
try {
const parsed = JSON.parse(line);
_.map(parsed, (value, key) => {
@ -149,7 +149,7 @@ export const LogsParsers: { [name: string]: LogsParser } = {
logfmt: {
buildMatcher: label => new RegExp(`(?:^|\\s)${label}=("[^"]*"|\\S+)`),
getFields: line => {
const fields = [];
const fields: string[] = [];
line.replace(new RegExp(LOGFMT_REGEXP, 'g'), substring => {
fields.push(substring.trim());
return '';
@ -273,9 +273,9 @@ export function makeSeriesForLogs(rows: LogRowModel[], intervalMs: number): Time
// intervalMs = intervalMs * 10;
// Graph time series by log level
const seriesByLevel = {};
const seriesByLevel: any = {};
const bucketSize = intervalMs * 10;
const seriesList = [];
const seriesList: any[] = [];
for (const row of rows) {
let series = seriesByLevel[row.logLevel];
@ -312,7 +312,7 @@ export function makeSeriesForLogs(rows: LogRowModel[], intervalMs: number): Time
}
return seriesList.map(series => {
series.datapoints.sort((a, b) => {
series.datapoints.sort((a: number[], b: number[]) => {
return a[1] - b[1];
});

@ -15,7 +15,7 @@ export class NavModelSrv {
return _.find(this.navItems, { id: 'cfg' });
}
getNav(...args) {
getNav(...args: string[]) {
let children = this.navItems;
const nav = {
breadcrumbs: [],

@ -1,4 +1,4 @@
let templates = (require as any).context('../', true, /\.html$/);
templates.keys().forEach(key => {
templates.keys().forEach((key: string) => {
templates(key);
});

@ -4,7 +4,7 @@ export class Profiler {
$rootScope: any;
window: any;
init(config, $rootScope) {
init(config: any, $rootScope: any) {
this.$rootScope = $rootScope;
this.window = window;
@ -13,7 +13,7 @@ export class Profiler {
}
}
renderingCompleted(panelId) {
renderingCompleted() {
// add render counter to root scope
// used by phantomjs render.js to know when panel has rendered
this.panelsRendered = (this.panelsRendered || 0) + 1;

@ -29,7 +29,7 @@ export class BackendSrv {
return this.request({ method: 'DELETE', url });
}
post(url: string, data: any) {
post(url: string, data?: any) {
return this.request({ method: 'POST', url, data });
}

@ -2,39 +2,51 @@ import _ from 'lodash';
import coreModule from '../core_module';
/** @ngInject */
export function uiSegmentSrv(this: any, $sce, templateSrv) {
export function uiSegmentSrv(this: any, $sce: any, templateSrv: any) {
const self = this;
function MetricSegment(this: any, options) {
if (options === '*' || options.value === '*') {
this.value = '*';
this.html = $sce.trustAsHtml('<i class="fa fa-asterisk"><i>');
this.type = options.type;
this.expandable = true;
return;
}
class MetricSegment {
value: string;
html: any;
type: any;
expandable: boolean;
text: string;
cssClass: string;
fake: boolean;
custom: boolean;
selectMode: any;
constructor(options: any) {
if (options === '*' || options.value === '*') {
this.value = '*';
this.html = $sce.trustAsHtml('<i class="fa fa-asterisk"><i>');
this.type = options.type;
this.expandable = true;
return;
}
if (_.isString(options)) {
this.value = options;
this.html = $sce.trustAsHtml(templateSrv.highlightVariablesAsHtml(this.value));
return;
}
if (_.isString(options)) {
this.value = options;
this.html = $sce.trustAsHtml(templateSrv.highlightVariablesAsHtml(this.value));
return;
}
// temp hack to work around legacy inconsistency in segment model
this.text = options.value;
this.cssClass = options.cssClass;
this.custom = options.custom;
this.type = options.type;
this.fake = options.fake;
this.value = options.value;
this.selectMode = options.selectMode;
this.type = options.type;
this.expandable = options.expandable;
this.html = options.html || $sce.trustAsHtml(templateSrv.highlightVariablesAsHtml(this.value));
// temp hack to work around legacy inconsistency in segment model
this.text = options.value;
this.cssClass = options.cssClass;
this.custom = options.custom;
this.type = options.type;
this.fake = options.fake;
this.value = options.value;
this.selectMode = options.selectMode;
this.type = options.type;
this.expandable = options.expandable;
this.html = options.html || $sce.trustAsHtml(templateSrv.highlightVariablesAsHtml(this.value));
}
}
this.getSegmentForValue = function(value, fallbackText) {
this.getSegmentForValue = function(value: string, fallbackText: string) {
if (value) {
return this.newSegment(value);
} else {
@ -46,38 +58,38 @@ export function uiSegmentSrv(this: any, $sce, templateSrv) {
return new MetricSegment({ value: 'select measurement', fake: true });
};
this.newFake = (text, type, cssClass) => {
this.newFake = (text: string, type: string, cssClass: string) => {
return new MetricSegment({ value: text, fake: true, type: type, cssClass: cssClass });
};
this.newSegment = options => {
this.newSegment = (options: any) => {
return new MetricSegment(options);
};
this.newKey = key => {
this.newKey = (key: string) => {
return new MetricSegment({ value: key, type: 'key', cssClass: 'query-segment-key' });
};
this.newKeyValue = value => {
this.newKeyValue = (value: string) => {
return new MetricSegment({ value: value, type: 'value', cssClass: 'query-segment-value' });
};
this.newCondition = condition => {
this.newCondition = (condition: string) => {
return new MetricSegment({ value: condition, type: 'condition', cssClass: 'query-keyword' });
};
this.newOperator = op => {
this.newOperator = (op: string) => {
return new MetricSegment({ value: op, type: 'operator', cssClass: 'query-segment-operator' });
};
this.newOperators = ops => {
this.newOperators = (ops: string[]) => {
return _.map(ops, op => {
return new MetricSegment({ value: op, type: 'operator', cssClass: 'query-segment-operator' });
});
};
this.transformToSegments = (addTemplateVars, variableTypeFilter) => {
return results => {
this.transformToSegments = (addTemplateVars: boolean, variableTypeFilter: string) => {
return (results: any[]) => {
const segments = _.map(results, segment => {
return self.newSegment({ value: segment.text, expandable: segment.expandable });
});

@ -26,15 +26,19 @@ export default class TableModel implements TableData {
if (table) {
if (table.columns) {
table.columns.forEach(col => this.addColumn(col));
for (const col of table.columns) {
this.addColumn(col);
}
}
if (table.rows) {
table.rows.forEach(row => this.addRow(row));
for (const row of table.rows) {
this.addRow(row);
}
}
}
}
sort(options) {
sort(options: { col: number; desc: boolean }) {
if (options.col === null || this.columns.length <= options.col) {
return;
}
@ -54,21 +58,21 @@ export default class TableModel implements TableData {
this.columns[options.col].desc = options.desc;
}
addColumn(col) {
addColumn(col: Column) {
if (!this.columnMap[col.text]) {
this.columns.push(col);
this.columnMap[col.text] = col;
}
}
addRow(row) {
addRow(row: any[]) {
this.rows.push(row);
}
}
// Returns true if both rows have matching non-empty fields as well as matching
// indexes where one field is empty and the other is not
function areRowsMatching(columns, row, otherRow) {
function areRowsMatching(columns: Column[], row: any[], otherRow: any[]) {
let foundFieldToMatch = false;
for (let columnIndex = 0; columnIndex < columns.length; columnIndex++) {
if (row[columnIndex] !== undefined && otherRow[columnIndex] !== undefined) {
@ -96,7 +100,7 @@ export function mergeTablesIntoModel(dst?: TableModel, ...tables: TableModel[]):
}
// Track column indexes of union: name -> index
const columnNames = {};
const columnNames: { [key: string]: any } = {};
// Union of all non-value columns
const columnsUnion = tables.slice().reduce((acc, series) => {
@ -119,7 +123,7 @@ export function mergeTablesIntoModel(dst?: TableModel, ...tables: TableModel[]):
const flattenedRows = tables.reduce((acc, series, seriesIndex) => {
const mapper = columnIndexMapper[seriesIndex];
series.rows.forEach(row => {
const alteredRow = [];
const alteredRow: any[] = [];
// Shifting entries according to index mapper
mapper.forEach((to, from) => {
alteredRow[to] = row[from];
@ -130,7 +134,8 @@ export function mergeTablesIntoModel(dst?: TableModel, ...tables: TableModel[]):
}, []);
// Merge rows that have same values for columns
const mergedRows = {};
const mergedRows: { [key: string]: any } = {};
const compactedRows = flattenedRows.reduce((acc, row, rowIndex) => {
if (!mergedRows[rowIndex]) {
// Look from current row onwards

@ -1,8 +1,8 @@
import { getFlotTickDecimals } from 'app/core/utils/ticks';
import _ from 'lodash';
import { getValueFormat, stringToJsRegex } from '@grafana/ui';
import { getValueFormat, stringToJsRegex, ValueFormatter, DecimalCount } from '@grafana/ui';
function matchSeriesOverride(aliasOrRegex, seriesAlias) {
function matchSeriesOverride(aliasOrRegex: string, seriesAlias: string) {
if (!aliasOrRegex) {
return false;
}
@ -15,7 +15,7 @@ function matchSeriesOverride(aliasOrRegex, seriesAlias) {
return aliasOrRegex === seriesAlias;
}
function translateFillOption(fill) {
function translateFillOption(fill: number) {
return fill === 0 ? 0.001 : fill / 10;
}
@ -25,7 +25,7 @@ function translateFillOption(fill) {
* @param panel
* @param height
*/
export function updateLegendValues(data: TimeSeries[], panel, height) {
export function updateLegendValues(data: TimeSeries[], panel: any, height: number) {
for (let i = 0; i < data.length; i++) {
const series = data[i];
const yaxes = panel.yaxes;
@ -97,7 +97,7 @@ export default class TimeSeries {
flotpairs: any;
unit: any;
constructor(opts) {
constructor(opts: any) {
this.datapoints = opts.datapoints;
this.label = opts.alias;
this.id = opts.alias;
@ -112,7 +112,7 @@ export default class TimeSeries {
this.hasMsResolution = this.isMsResolutionNeeded();
}
applySeriesOverrides(overrides) {
applySeriesOverrides(overrides: any[]) {
this.lines = {};
this.dashes = {
dashLength: [],
@ -192,7 +192,7 @@ export default class TimeSeries {
}
}
getFlotPairs(fillStyle) {
getFlotPairs(fillStyle: string) {
const result = [];
this.stats.total = 0;
@ -314,13 +314,13 @@ export default class TimeSeries {
return result;
}
updateLegendValues(formater, decimals, scaledDecimals) {
updateLegendValues(formater: ValueFormatter, decimals: DecimalCount, scaledDecimals: DecimalCount) {
this.valueFormater = formater;
this.decimals = decimals;
this.scaledDecimals = scaledDecimals;
}
formatValue(value) {
formatValue(value: number) {
if (!_.isFinite(value)) {
value = null; // Prevent NaN formatting
}
@ -339,7 +339,7 @@ export default class TimeSeries {
return false;
}
hideFromLegend(options) {
hideFromLegend(options: any) {
if (options.hideEmpty && this.allIsNull) {
return true;
}

@ -3,7 +3,7 @@ import { connect } from 'react-redux';
import { store } from '../../store/store';
export function connectWithStore(WrappedComponent, ...args) {
const ConnectedWrappedComponent = connect(...args)(WrappedComponent);
const ConnectedWrappedComponent = (connect as any)(...args)(WrappedComponent);
return props => {
return <ConnectedWrappedComponent {...props} store={store} />;

@ -1,8 +1,11 @@
import { BackendSrv } from 'app/core/services/backend_srv';
import { NavModelSrv } from 'app/core/core';
export default class AdminEditOrgCtrl {
/** @ngInject */
constructor($scope, $routeParams, backendSrv, $location, navModelSrv) {
constructor($scope: any, $routeParams: any, backendSrv: BackendSrv, $location: any, navModelSrv: NavModelSrv) {
$scope.init = () => {
$scope.navModel = navModelSrv.getNav('admin', 'global-orgs', 0);
$scope.navModel = navModelSrv.getNav('admin', 'global-orgs');
if ($routeParams.id) {
$scope.getOrg($routeParams.id);
@ -10,14 +13,14 @@ export default class AdminEditOrgCtrl {
}
};
$scope.getOrg = id => {
backendSrv.get('/api/orgs/' + id).then(org => {
$scope.getOrg = (id: number) => {
backendSrv.get('/api/orgs/' + id).then((org: any) => {
$scope.org = org;
});
};
$scope.getOrgUsers = id => {
backendSrv.get('/api/orgs/' + id + '/users').then(orgUsers => {
$scope.getOrgUsers = (id: number) => {
backendSrv.get('/api/orgs/' + id + '/users').then((orgUsers: any) => {
$scope.orgUsers = orgUsers;
});
};
@ -32,11 +35,11 @@ export default class AdminEditOrgCtrl {
});
};
$scope.updateOrgUser = orgUser => {
$scope.updateOrgUser = (orgUser: any) => {
backendSrv.patch('/api/orgs/' + orgUser.orgId + '/users/' + orgUser.userId, orgUser);
};
$scope.removeOrgUser = orgUser => {
$scope.removeOrgUser = (orgUser: any) => {
backendSrv.delete('/api/orgs/' + orgUser.orgId + '/users/' + orgUser.userId).then(() => {
$scope.getOrgUsers($scope.org.id);
});

@ -1,12 +1,15 @@
import _ from 'lodash';
import { BackendSrv } from 'app/core/services/backend_srv';
import { NavModelSrv } from 'app/core/core';
import { User } from 'app/core/services/context_srv';
export default class AdminEditUserCtrl {
/** @ngInject */
constructor($scope, $routeParams, backendSrv, $location, navModelSrv) {
constructor($scope: any, $routeParams: any, backendSrv: BackendSrv, $location: any, navModelSrv: NavModelSrv) {
$scope.user = {};
$scope.newOrg = { name: '', role: 'Editor' };
$scope.permissions = {};
$scope.navModel = navModelSrv.getNav('admin', 'global-users', 0);
$scope.navModel = navModelSrv.getNav('admin', 'global-users');
$scope.init = () => {
if ($routeParams.id) {
@ -15,8 +18,8 @@ export default class AdminEditUserCtrl {
}
};
$scope.getUser = id => {
backendSrv.get('/api/users/' + id).then(user => {
$scope.getUser = (id: number) => {
backendSrv.get('/api/users/' + id).then((user: User) => {
$scope.user = user;
$scope.user_id = id;
$scope.permissions.isGrafanaAdmin = user.isGrafanaAdmin;
@ -52,8 +55,8 @@ export default class AdminEditUserCtrl {
});
};
$scope.getUserOrgs = id => {
backendSrv.get('/api/users/' + id + '/orgs').then(orgs => {
$scope.getUserOrgs = (id: number) => {
backendSrv.get('/api/users/' + id + '/orgs').then((orgs: any) => {
$scope.orgs = orgs;
});
};
@ -68,11 +71,11 @@ export default class AdminEditUserCtrl {
});
};
$scope.updateOrgUser = orgUser => {
$scope.updateOrgUser = (orgUser: { orgId: string }) => {
backendSrv.patch('/api/orgs/' + orgUser.orgId + '/users/' + $scope.user_id, orgUser).then(() => {});
};
$scope.removeOrgUser = orgUser => {
$scope.removeOrgUser = (orgUser: { orgId: string }) => {
backendSrv.delete('/api/orgs/' + orgUser.orgId + '/users/' + $scope.user_id).then(() => {
$scope.getUser($scope.user_id);
$scope.getUserOrgs($scope.user_id);
@ -81,13 +84,13 @@ export default class AdminEditUserCtrl {
$scope.orgsSearchCache = [];
$scope.searchOrgs = (queryStr, callback) => {
$scope.searchOrgs = (queryStr: any, callback: any) => {
if ($scope.orgsSearchCache.length > 0) {
callback(_.map($scope.orgsSearchCache, 'name'));
return;
}
backendSrv.get('/api/orgs', { query: '' }).then(result => {
backendSrv.get('/api/orgs', { query: '' }).then((result: any) => {
$scope.orgsSearchCache = result;
callback(_.map(result, 'name'));
});
@ -101,6 +104,7 @@ export default class AdminEditUserCtrl {
const orgInfo: any = _.find($scope.orgsSearchCache, {
name: $scope.newOrg.name,
});
if (!orgInfo) {
return;
}

@ -1,18 +1,21 @@
import { BackendSrv } from 'app/core/services/backend_srv';
import { NavModelSrv } from 'app/core/core';
export default class AdminListOrgsCtrl {
/** @ngInject */
constructor($scope, backendSrv, navModelSrv) {
constructor($scope: any, backendSrv: BackendSrv, navModelSrv: NavModelSrv) {
$scope.init = () => {
$scope.navModel = navModelSrv.getNav('admin', 'global-orgs', 0);
$scope.navModel = navModelSrv.getNav('admin', 'global-orgs');
$scope.getOrgs();
};
$scope.getOrgs = () => {
backendSrv.get('/api/orgs').then(orgs => {
backendSrv.get('/api/orgs').then((orgs: any) => {
$scope.orgs = orgs;
});
};
$scope.deleteOrg = org => {
$scope.deleteOrg = (org: any) => {
$scope.appEvent('confirm-modal', {
title: 'Delete',
text: 'Do you want to delete organization ' + org.name + '?',

@ -1,6 +1,9 @@
import { BackendSrv } from 'app/core/services/backend_srv';
import { NavModelSrv } from 'app/core/core';
export default class AdminListUsersCtrl {
users: any;
pages = [];
pages: any[] = [];
perPage = 50;
page = 1;
totalPages: number;
@ -9,8 +12,8 @@ export default class AdminListUsersCtrl {
navModel: any;
/** @ngInject */
constructor(private $scope, private backendSrv, navModelSrv) {
this.navModel = navModelSrv.getNav('admin', 'global-users', 0);
constructor(private $scope: any, private backendSrv: BackendSrv, navModelSrv: NavModelSrv) {
this.navModel = navModelSrv.getNav('admin', 'global-users');
this.query = '';
this.getUsers();
}
@ -18,7 +21,7 @@ export default class AdminListUsersCtrl {
getUsers() {
this.backendSrv
.get(`/api/users/search?perpage=${this.perPage}&page=${this.page}&query=${this.query}`)
.then(result => {
.then((result: any) => {
this.users = result.users;
this.page = result.page;
this.perPage = result.perPage;
@ -32,12 +35,12 @@ export default class AdminListUsersCtrl {
});
}
navigateToPage(page) {
navigateToPage(page: any) {
this.page = page.page;
this.getUsers();
}
deleteUser(user) {
deleteUser(user: any) {
this.$scope.appEvent('confirm-modal', {
title: 'Delete',
text: 'Do you want to delete ' + user.login + '?',

@ -1,4 +1,5 @@
import React from 'react';
// @ts-ignore
import renderer from 'react-test-renderer';
import { ServerStats } from './ServerStats';
import { createNavModel } from 'test/mocks/common';

@ -1,4 +1,6 @@
import config from 'app/core/config';
import { BackendSrv } from 'app/core/services/backend_srv';
import { NavModelSrv } from 'app/core/core';
export default class StyleGuideCtrl {
theme: string;
@ -8,8 +10,8 @@ export default class StyleGuideCtrl {
navModel: any;
/** @ngInject */
constructor(private $routeParams, private backendSrv, navModelSrv) {
this.navModel = navModelSrv.getNav('admin', 'styleguide', 0);
constructor(private $routeParams: any, private backendSrv: BackendSrv, navModelSrv: NavModelSrv) {
this.navModel = navModelSrv.getNav('admin', 'styleguide');
this.theme = config.bootData.user.lightTheme ? 'light' : 'dark';
}

@ -5,15 +5,17 @@ import AdminEditOrgCtrl from './AdminEditOrgCtrl';
import StyleGuideCtrl from './StyleGuideCtrl';
import coreModule from 'app/core/core_module';
import { BackendSrv } from 'app/core/services/backend_srv';
import { NavModelSrv } from 'app/core/core';
class AdminSettingsCtrl {
navModel: any;
/** @ngInject */
constructor($scope, backendSrv, navModelSrv) {
this.navModel = navModelSrv.getNav('admin', 'server-settings', 0);
constructor($scope: any, backendSrv: BackendSrv, navModelSrv: NavModelSrv) {
this.navModel = navModelSrv.getNav('admin', 'server-settings');
backendSrv.get('/api/admin/settings').then(settings => {
backendSrv.get('/api/admin/settings').then((settings: any) => {
$scope.settings = settings;
});
}
@ -23,8 +25,8 @@ class AdminHomeCtrl {
navModel: any;
/** @ngInject */
constructor(navModelSrv) {
this.navModel = navModelSrv.getNav('admin', 0);
constructor(navModelSrv: NavModelSrv) {
this.navModel = navModelSrv.getNav('admin');
}
}

@ -3,7 +3,7 @@ import { shallow } from 'enzyme';
import AlertRuleItem, { Props } from './AlertRuleItem';
jest.mock('react-redux', () => ({
connect: () => params => params,
connect: () => (params: any) => params,
}));
const setup = (propOverrides?: object) => {

@ -1,4 +1,5 @@
import React, { PureComponent } from 'react';
// @ts-ignore
import Highlighter from 'react-highlight-words';
import classNames from 'classnames';
import { AlertRule } from '../../types';

@ -5,9 +5,14 @@ import { QueryPart } from 'app/core/components/query_part/query_part';
import alertDef from './state/alertDef';
import config from 'app/core/config';
import appEvents from 'app/core/app_events';
import { BackendSrv } from 'app/core/services/backend_srv';
import { DashboardSrv } from '../dashboard/services/DashboardSrv';
import DatasourceSrv from '../plugins/datasource_srv';
import { DataQuery } from '@grafana/ui/src/types/datasource';
import { PanelModel } from 'app/features/dashboard/state';
export class AlertTabCtrl {
panel: any;
panel: PanelModel;
panelCtrl: any;
subTabIndex: number;
conditionTypes: any;
@ -17,21 +22,21 @@ export class AlertTabCtrl {
evalOperators: any;
noDataModes: any;
executionErrorModes: any;
addNotificationSegment;
notifications;
alertNotifications;
addNotificationSegment: any;
notifications: any;
alertNotifications: any;
error: string;
appSubUrl: string;
alertHistory: any;
/** @ngInject */
constructor(
private $scope,
private backendSrv,
private dashboardSrv,
private uiSegmentSrv,
private $q,
private datasourceSrv
private $scope: any,
private backendSrv: BackendSrv,
private dashboardSrv: DashboardSrv,
private uiSegmentSrv: any,
private $q: any,
private datasourceSrv: DatasourceSrv
) {
this.panelCtrl = $scope.ctrl;
this.panel = this.panelCtrl.panel;
@ -65,7 +70,7 @@ export class AlertTabCtrl {
this.alertNotifications = [];
this.alertHistory = [];
return this.backendSrv.get('/api/alert-notifications').then(res => {
return this.backendSrv.get('/api/alert-notifications').then((res: any) => {
this.notifications = res;
this.initModel();
@ -76,7 +81,7 @@ export class AlertTabCtrl {
getAlertHistory() {
this.backendSrv
.get(`/api/annotations?dashboardId=${this.panelCtrl.dashboard.id}&panelId=${this.panel.id}&limit=50&type=alert`)
.then(res => {
.then((res: any) => {
this.alertHistory = _.map(res, ah => {
ah.time = this.dashboardSrv.getCurrent().formatDate(ah.time, 'MMM D, YYYY HH:mm:ss');
ah.stateModel = alertDef.getStateDisplayModel(ah.newState);
@ -86,7 +91,7 @@ export class AlertTabCtrl {
});
}
getNotificationIcon(type): string {
getNotificationIcon(type: string): string {
switch (type) {
case 'email':
return 'fa fa-envelope';
@ -114,20 +119,12 @@ export class AlertTabCtrl {
getNotifications() {
return this.$q.when(
this.notifications.map(item => {
this.notifications.map((item: any) => {
return this.uiSegmentSrv.newSegment(item.name);
})
);
}
changeTabIndex(newTabIndex) {
this.subTabIndex = newTabIndex;
if (this.subTabIndex === 2) {
this.getAlertHistory();
}
}
notificationAdded() {
const model: any = _.find(this.notifications, {
name: this.addNotificationSegment.value,
@ -154,7 +151,7 @@ export class AlertTabCtrl {
this.addNotificationSegment.fake = true;
}
removeNotification(an) {
removeNotification(an: any) {
// remove notifiers refeered to by id and uid to support notifiers added
// before and after we added support for uid
_.remove(this.alert.notifications, (n: any) => n.uid === an.uid || n.id === an.id);
@ -220,7 +217,7 @@ export class AlertTabCtrl {
this.panelCtrl.render();
}
graphThresholdChanged(evt) {
graphThresholdChanged(evt: any) {
for (const condition of this.alert.conditions) {
if (condition.type === 'query') {
condition.evaluator.params[evt.handleIndex] = evt.threshold.value;
@ -234,8 +231,8 @@ export class AlertTabCtrl {
return {
type: 'query',
query: { params: ['A', '5m', 'now'] },
reducer: { type: 'avg', params: [] },
evaluator: { type: 'gt', params: [null] },
reducer: { type: 'avg', params: [] as any[] },
evaluator: { type: 'gt', params: [null] as any[] },
operator: { type: 'and' },
};
}
@ -246,7 +243,7 @@ export class AlertTabCtrl {
}
let firstTarget;
let foundTarget = null;
let foundTarget: DataQuery = null;
for (const condition of this.alert.conditions) {
if (condition.type !== 'query') {
@ -285,7 +282,7 @@ export class AlertTabCtrl {
}
}
buildConditionModel(source) {
buildConditionModel(source: any) {
const cm: any = { source: source, type: source.type };
cm.queryPart = new QueryPart(source.query, alertDef.alertQueryDef);
@ -296,7 +293,7 @@ export class AlertTabCtrl {
return cm;
}
handleQueryPartEvent(conditionModel, evt) {
handleQueryPartEvent(conditionModel: any, evt: any) {
switch (evt.name) {
case 'action-remove-part': {
break;
@ -317,7 +314,7 @@ export class AlertTabCtrl {
}
}
handleReducerPartEvent(conditionModel, evt) {
handleReducerPartEvent(conditionModel: any, evt: any) {
switch (evt.name) {
case 'action': {
conditionModel.source.reducer.type = evt.action.value;
@ -336,7 +333,7 @@ export class AlertTabCtrl {
}
}
addCondition(type) {
addCondition(type: string) {
const condition = this.buildDefaultCondition();
// add to persited model
this.alert.conditions.push(condition);
@ -344,7 +341,7 @@ export class AlertTabCtrl {
this.conditionModels.push(this.buildConditionModel(condition));
}
removeCondition(index) {
removeCondition(index: number) {
this.alert.conditions.splice(index, 1);
this.conditionModels.splice(index, 1);
}
@ -378,7 +375,7 @@ export class AlertTabCtrl {
this.panelCtrl.render();
}
evaluatorTypeChanged(evaluator) {
evaluatorTypeChanged(evaluator: any) {
// ensure params array is correct length
switch (evaluator.type) {
case 'lt':
@ -411,7 +408,7 @@ export class AlertTabCtrl {
dashboardId: this.panelCtrl.dashboard.id,
panelId: this.panel.id,
})
.then(res => {
.then(() => {
this.alertHistory = [];
this.panelCtrl.refresh();
});

@ -1,5 +1,6 @@
import _ from 'lodash';
import { appEvents, coreModule } from 'app/core/core';
import { appEvents, coreModule, NavModelSrv } from 'app/core/core';
import { BackendSrv } from 'app/core/services/backend_srv';
export class AlertNotificationEditCtrl {
theForm: any;
@ -24,8 +25,14 @@ export class AlertNotificationEditCtrl {
getFrequencySuggestion: any;
/** @ngInject */
constructor(private $routeParams, private backendSrv, private $location, private $templateCache, navModelSrv) {
this.navModel = navModelSrv.getNav('alerting', 'channels', 0);
constructor(
private $routeParams: any,
private backendSrv: BackendSrv,
private $location: any,
private $templateCache: any,
navModelSrv: NavModelSrv
) {
this.navModel = navModelSrv.getNav('alerting', 'channels');
this.isNew = !this.$routeParams.id;
this.getFrequencySuggestion = () => {
@ -34,7 +41,7 @@ export class AlertNotificationEditCtrl {
this.backendSrv
.get(`/api/alert-notifiers`)
.then(notifiers => {
.then((notifiers: any) => {
this.notifiers = notifiers;
// add option templates
@ -48,14 +55,14 @@ export class AlertNotificationEditCtrl {
return _.defaults(this.model, this.defaults);
}
return this.backendSrv.get(`/api/alert-notifications/${this.$routeParams.id}`).then(result => {
return this.backendSrv.get(`/api/alert-notifications/${this.$routeParams.id}`).then((result: any) => {
this.navModel.breadcrumbs.push({ text: result.name });
this.navModel.node = { text: result.name };
result.settings = _.defaults(result.settings, this.defaults.settings);
return result;
});
})
.then(model => {
.then((model: any) => {
this.model = model;
this.notifierTemplateId = this.getNotifierTemplateId(this.model.type);
});
@ -69,11 +76,11 @@ export class AlertNotificationEditCtrl {
if (this.model.id) {
this.backendSrv
.put(`/api/alert-notifications/${this.model.id}`, this.model)
.then(res => {
.then((res: any) => {
this.model = res;
appEvents.emit('alert-success', ['Notification updated', '']);
})
.catch(err => {
.catch((err: any) => {
if (err.data && err.data.error) {
appEvents.emit('alert-error', [err.data.error]);
}
@ -81,11 +88,11 @@ export class AlertNotificationEditCtrl {
} else {
this.backendSrv
.post(`/api/alert-notifications`, this.model)
.then(res => {
.then((res: any) => {
appEvents.emit('alert-success', ['Notification created', '']);
this.$location.path('alerting/notifications');
})
.catch(err => {
.catch((err: any) => {
if (err.data && err.data.error) {
appEvents.emit('alert-error', [err.data.error]);
}
@ -93,7 +100,7 @@ export class AlertNotificationEditCtrl {
}
}
getNotifierTemplateId(type) {
getNotifierTemplateId(type: string) {
return `notifier-options-${type}`;
}
@ -114,7 +121,7 @@ export class AlertNotificationEditCtrl {
settings: this.model.settings,
};
this.backendSrv.post(`/api/alert-notifications/test`, payload).then(res => {
this.backendSrv.post(`/api/alert-notifications/test`, payload).then((res: any) => {
appEvents.emit('alert-success', ['Test notification sent', '']);
});
}

@ -1,24 +1,25 @@
import { coreModule } from 'app/core/core';
import { coreModule, NavModelSrv } from 'app/core/core';
import { BackendSrv } from 'app/core/services/backend_srv';
export class AlertNotificationsListCtrl {
notifications: any;
navModel: any;
/** @ngInject */
constructor(private backendSrv, navModelSrv) {
constructor(private backendSrv: BackendSrv, navModelSrv: NavModelSrv) {
this.loadNotifications();
this.navModel = navModelSrv.getNav('alerting', 'channels', 0);
this.navModel = navModelSrv.getNav('alerting', 'channels');
}
loadNotifications() {
this.backendSrv.get(`/api/alert-notifications`).then(result => {
this.backendSrv.get(`/api/alert-notifications`).then((result: any) => {
this.notifications = result;
});
}
deleteNotification(id) {
deleteNotification(id: number) {
this.backendSrv.delete(`/api/alert-notifications/${id}`).then(() => {
this.notifications = this.notifications.filter(notification => {
this.notifications = this.notifications.filter((notification: any) => {
return notification.id !== id;
});
});

@ -15,7 +15,7 @@ interface State {
}
class StateHistory extends PureComponent<Props, State> {
state = {
state: State = {
stateHistoryItems: [],
};
@ -24,8 +24,8 @@ class StateHistory extends PureComponent<Props, State> {
getBackendSrv()
.get(`/api/annotations?dashboardId=${dashboard.id}&panelId=${panelId}&limit=50&type=alert`)
.then(res => {
const items = res.map(item => {
.then((res: any[]) => {
const items = res.map((item: any) => {
return {
stateModel: alertDef.getStateDisplayModel(item.newState),
time: dashboard.formatDate(item.time, 'MMM D, YYYY HH:mm:ss'),

@ -1,5 +1,7 @@
import { PanelModel } from 'app/features/dashboard/state';
export class ThresholdMapper {
static alertToGraphThresholds(panel) {
static alertToGraphThresholds(panel: PanelModel) {
for (let i = 0; i < panel.alert.conditions.length; i++) {
const condition = panel.alert.conditions[i];
if (condition.type !== 'query') {
@ -7,7 +9,7 @@ export class ThresholdMapper {
}
const evaluator = condition.evaluator;
const thresholds = (panel.thresholds = []);
const thresholds: any[] = (panel.thresholds = []);
switch (evaluator.type) {
case 'gt': {

@ -57,12 +57,12 @@ const noDataModes = [
const executionErrorModes = [{ text: 'Alerting', value: 'alerting' }, { text: 'Keep Last State', value: 'keep_state' }];
function createReducerPart(model) {
function createReducerPart(model: any) {
const def = new QueryPartDef({ type: model.type, defaultParams: [] });
return new QueryPart(model, def);
}
function getStateDisplayModel(state) {
function getStateDisplayModel(state: string) {
switch (state) {
case 'ok': {
return {
@ -111,7 +111,7 @@ function getStateDisplayModel(state) {
throw { message: 'Unknown alert state' };
}
function joinEvalMatches(matches, separator: string) {
function joinEvalMatches(matches: any, separator: string) {
return _.reduce(
matches,
(res, ev) => {
@ -130,7 +130,7 @@ function joinEvalMatches(matches, separator: string) {
).join(separator);
}
function getAlertAnnotationInfo(ah) {
function getAlertAnnotationInfo(ah: any) {
// backward compatibility, can be removed in grafana 5.x
// old way stored evalMatches in data property directly,
// new way stores it in evalMatches property on new data object

@ -85,7 +85,7 @@ describe('Alert rules', () => {
};
const result = alertRulesReducer(initialState, action);
expect(result.items).toEqual(payload);
expect(result.items.length).toEqual(payload.length);
expect(result.items[0].stateClass).toEqual('alert-state-critical');
});
});

@ -5,14 +5,18 @@ import { dateTime } from '@grafana/ui/src/utils/moment_wrapper';
export const initialState: AlertRulesState = { items: [], searchQuery: '', isLoading: false };
function convertToAlertRule(rule, state): AlertRule {
function convertToAlertRule(dto: AlertRuleDTO, state: string): AlertRule {
const stateModel = alertDef.getStateDisplayModel(state);
rule.stateText = stateModel.text;
rule.stateIcon = stateModel.iconClass;
rule.stateClass = stateModel.stateClass;
rule.stateAge = dateTime(rule.newStateDate)
.fromNow()
.replace(' ago', '');
const rule: AlertRule = {
...dto,
stateText: stateModel.text,
stateIcon: stateModel.iconClass,
stateClass: stateModel.stateClass,
stateAge: dateTime(dto.newStateDate)
.fromNow()
.replace(' ago', ''),
};
if (rule.state !== 'paused') {
if (rule.executionError) {

@ -3,7 +3,7 @@ import { getSearchQuery, getAlertRuleItems } from './selectors';
describe('Get search query', () => {
it('should get search query', () => {
const state = { searchQuery: 'dashboard' };
const result = getSearchQuery(state);
const result = getSearchQuery(state as any);
expect(result).toEqual(state.searchQuery);
});
@ -29,7 +29,7 @@ describe('Get alert rule items', () => {
searchQuery: '',
};
const result = getAlertRuleItems(state);
const result = getAlertRuleItems(state as any);
expect(result.length).toEqual(1);
});
@ -88,7 +88,7 @@ describe('Get alert rule items', () => {
searchQuery: 'dashboard',
};
const result = getAlertRuleItems(state);
const result = getAlertRuleItems(state as any);
expect(result.length).toEqual(3);
});
});

@ -1,6 +1,8 @@
export const getSearchQuery = state => state.searchQuery;
import { AlertRulesState } from 'app/types';
export const getAlertRuleItems = state => {
export const getSearchQuery = (state: AlertRulesState) => state.searchQuery;
export const getAlertRuleItems = (state: AlertRulesState) => {
const regex = new RegExp(state.searchQuery, 'i');
return state.items.filter(item => {

@ -234,7 +234,7 @@ export class PanelChrome extends PureComponent<Props, State> {
// image rendering (phantomjs/headless chrome) to know when to capture image
const loading = data.state;
if (loading === LoadingState.Done) {
profiler.renderingCompleted(panel.id);
profiler.renderingCompleted();
}
// do not render component until we have first data

@ -365,4 +365,4 @@ export default hot(module)(
mapStateToProps,
mapDispatchToProps
)(Explore)
);
) as React.ComponentType<{ exploreId: ExploreId }>;

@ -28,19 +28,22 @@ import { Emitter } from 'app/core/utils/emitter';
import { highlightLogsExpressionAction, removeQueryRowAction } from './state/actionTypes';
import QueryStatus from './QueryStatus';
interface QueryRowProps {
interface PropsFromParent {
exploreId: ExploreId;
index: number;
exploreEvents: Emitter;
}
interface QueryRowProps extends PropsFromParent {
addQueryRow: typeof addQueryRow;
changeQuery: typeof changeQuery;
className?: string;
exploreId: ExploreId;
datasourceInstance: ExploreDataSourceApi;
datasourceStatus: DataSourceStatus;
highlightLogsExpressionAction: typeof highlightLogsExpressionAction;
history: HistoryItem[];
index: number;
query: DataQuery;
modifyQueries: typeof modifyQueries;
exploreEvents: Emitter;
range: TimeRange;
removeQueryRowAction: typeof removeQueryRowAction;
runQueries: typeof runQueries;
@ -219,9 +222,7 @@ const mapDispatchToProps = {
runQueries,
};
export default hot(module)(
connect(
mapStateToProps,
mapDispatchToProps
)(QueryRow)
);
export default hot(module)(connect(
mapStateToProps,
mapDispatchToProps
)(QueryRow) as React.ComponentType<PropsFromParent>);

@ -36,6 +36,7 @@ export class Wrapper extends Component<WrapperProps> {
</ErrorBoundary>
)}
</div>
x
</CustomScrollbar>
</div>
);

@ -1,9 +1,6 @@
import { ThunkAction } from 'redux-thunk';
import { Organization, StoreState } from 'app/types';
import { Organization, ThunkResult } from 'app/types';
import { getBackendSrv } from 'app/core/services/backend_srv';
type ThunkResult<R> = ThunkAction<R, StoreState, undefined, any>;
export enum ActionTypes {
LoadOrganization = 'LOAD_ORGANIZATION',
SetOrganizationName = 'SET_ORGANIZATION_NAME',
@ -31,7 +28,7 @@ export const setOrganizationName = (orgName: string) => ({
export type Action = LoadOrganizationAction | SetOrganizationNameAction;
export function loadOrganization(): ThunkResult<void> {
export function loadOrganization(): ThunkResult<any> {
return async dispatch => {
const organizationResponse = await getBackendSrv().get('/api/org');
dispatch(organizationLoaded(organizationResponse));
@ -40,7 +37,7 @@ export function loadOrganization(): ThunkResult<void> {
};
}
export function updateOrganization() {
export function updateOrganization(): ThunkResult<any> {
return async (dispatch, getStore) => {
const organization = getStore().organization.organization;

@ -60,7 +60,7 @@ export class PanelCtrl {
}
renderingCompleted() {
profiler.renderingCompleted(this.panel.id);
profiler.renderingCompleted();
}
refresh() {

@ -137,7 +137,7 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
return escapedValues.join('|');
}
targetContainsTemplate(target) {
targetContainsTemplate(target: PromQuery) {
return this.templateSrv.variableExists(target.expr);
}

@ -8,7 +8,7 @@ export interface AlertRuleDTO {
state: string;
newStateDate: string;
evalDate: string;
evalData?: object;
evalData?: { noData?: boolean; evalMatches?: any };
executionError: string;
url: string;
}
@ -26,7 +26,7 @@ export interface AlertRule {
url: string;
info?: string;
executionError?: string;
evalData?: { noData: boolean };
evalData?: { noData?: boolean; evalMatches?: any };
}
export interface AlertRulesState {

@ -2,7 +2,7 @@
echo -e "Collecting code stats (typescript errors & more)"
ERROR_COUNT_LIMIT=5386
ERROR_COUNT_LIMIT=5150
DIRECTIVES_LIMIT=172
CONTROLLERS_LIMIT=139

@ -2219,6 +2219,14 @@
"@types/minimatch" "*"
"@types/node" "*"
"@types/hoist-non-react-statics@^3.3.0":
version "3.3.1"
resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f"
integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==
dependencies:
"@types/react" "*"
hoist-non-react-statics "^3.3.0"
"@types/inquirer@0.0.43":
version "0.0.43"
resolved "https://registry.yarnpkg.com/@types/inquirer/-/inquirer-0.0.43.tgz#1eb0bbb4648e6cc568bd396c1e989f620ad01273"
@ -2384,6 +2392,15 @@
dependencies:
"@types/react" "*"
"@types/react-redux@^7.0.8":
version "7.0.8"
resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.0.8.tgz#c928863058e334d41031c6bedd0f113bc514e234"
integrity sha512-vIBC15E84ehN6RzdGwRVa41whp9e4CkfPm+WfD0r6y6vqBf4tQPKZeKEBfLLM8k79uSwQC7rh3rH/MFaN1IESQ==
dependencies:
"@types/hoist-non-react-statics" "^3.3.0"
"@types/react" "*"
redux "^4.0.0"
"@types/react-select@2.0.15":
version "2.0.15"
resolved "https://registry.yarnpkg.com/@types/react-select/-/react-select-2.0.15.tgz#51d607667f59a12e980abcc5bbf9636307293e44"
@ -14671,7 +14688,7 @@ redux-thunk@2.3.0:
resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.3.0.tgz#51c2c19a185ed5187aaa9a2d08b666d0d6467622"
integrity sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw==
redux@4.0.1:
redux@4.0.1, redux@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.1.tgz#436cae6cc40fbe4727689d7c8fae44808f1bfef5"
integrity sha512-R7bAtSkk7nY6O/OYMVR9RiBI+XghjF9rlbl5806HJbQph0LJVHZrU5oaO4q70eUKiqMRqm4y07KLTlMZ2BlVmg==

Loading…
Cancel
Save