mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Chore: No implict any fixes (#17020)
This commit is contained in:
@@ -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>');
|
||||
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;
|
||||
}
|
||||
|
||||
// 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.expandable = true;
|
||||
return;
|
||||
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));
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
|
19
yarn.lock
19
yarn.lock
@@ -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==
|
||||
|
Reference in New Issue
Block a user