diff --git a/package.json b/package.json index 69309e2e341..85c953f907a 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/packages/grafana-ui/src/types/datasource.ts b/packages/grafana-ui/src/types/datasource.ts index 2622efd3ed5..3be0bae09dd 100644 --- a/packages/grafana-ui/src/types/datasource.ts +++ b/packages/grafana-ui/src/types/datasource.ts @@ -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< diff --git a/public/app/core/components/PasswordStrength.tsx b/public/app/core/components/PasswordStrength.tsx index 1d676a00a37..6c6bb697f65 100644 --- a/public/app/core/components/PasswordStrength.tsx +++ b/public/app/core/components/PasswordStrength.tsx @@ -5,7 +5,7 @@ export interface Props { } export class PasswordStrength extends React.Component { - constructor(props) { + constructor(props: Props) { super(props); } diff --git a/public/app/core/components/TagFilter/TagBadge.tsx b/public/app/core/components/TagFilter/TagBadge.tsx index b00b95b70cb..d7a0c897795 100644 --- a/public/app/core/components/TagFilter/TagBadge.tsx +++ b/public/app/core/components/TagFilter/TagBadge.tsx @@ -9,7 +9,7 @@ export interface Props { } export class TagBadge extends React.Component { - constructor(props) { + constructor(props: Props) { super(props); } diff --git a/public/app/core/components/TagFilter/TagFilter.tsx b/public/app/core/components/TagFilter/TagFilter.tsx index 967792a9f7b..89d3e8469b6 100644 --- a/public/app/core/components/TagFilter/TagFilter.tsx +++ b/public/app/core/components/TagFilter/TagFilter.tsx @@ -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 { 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 { 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 { 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 ( diff --git a/public/app/core/components/TagFilter/TagOption.tsx b/public/app/core/components/TagFilter/TagOption.tsx index 9db15aaca0b..4da6202bf3e 100644 --- a/public/app/core/components/TagFilter/TagOption.tsx +++ b/public/app/core/components/TagFilter/TagOption.tsx @@ -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'; diff --git a/public/app/core/components/TagFilter/TagValue.tsx b/public/app/core/components/TagFilter/TagValue.tsx index 43e41c7fdc2..0406ead16a6 100644 --- a/public/app/core/components/TagFilter/TagValue.tsx +++ b/public/app/core/components/TagFilter/TagValue.tsx @@ -9,18 +9,17 @@ export interface Props { } export class TagValue extends React.Component { - 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 ; } } diff --git a/public/app/core/components/ToggleButtonGroup/ToggleButtonGroup.tsx b/public/app/core/components/ToggleButtonGroup/ToggleButtonGroup.tsx index e550afc20c3..ce1f80c8dca 100644 --- a/public/app/core/components/ToggleButtonGroup/ToggleButtonGroup.tsx +++ b/public/app/core/components/ToggleButtonGroup/ToggleButtonGroup.tsx @@ -21,7 +21,7 @@ export default class ToggleButtonGroup extends PureComponent void; + onChange?: (value: any) => void; selected?: boolean; value: any; className?: string; @@ -37,7 +37,7 @@ export const ToggleButton: FC = ({ tooltip, onChange, }) => { - const onClick = event => { + const onClick = (event: React.SyntheticEvent) => { event.stopPropagation(); if (onChange) { onChange(value); diff --git a/public/app/core/components/dashboard_selector.ts b/public/app/core/components/dashboard_selector.ts index e1809f3d42c..f312c77f6a8 100644 --- a/public/app/core/components/dashboard_selector.ts +++ b/public/app/core/components/dashboard_selector.ts @@ -1,4 +1,5 @@ import coreModule from 'app/core/core_module'; +import { BackendSrv } from '../services/backend_srv'; const template = ` @@ -9,7 +10,7 @@ export class DashboardSelectorCtrl { options: any; /** @ngInject */ - constructor(private backendSrv) {} + constructor(private backendSrv: BackendSrv) {} $onInit() { this.options = [{ value: 0, text: 'Default' }]; diff --git a/public/app/core/components/info_popover.ts b/public/app/core/components/info_popover.ts index 2ada91b09f1..9c5694188d6 100644 --- a/public/app/core/components/info_popover.ts +++ b/public/app/core/components/info_popover.ts @@ -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: '', 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'; diff --git a/public/app/core/components/org_switcher.ts b/public/app/core/components/org_switcher.ts index dc8f00f0fdb..0e25482e190 100644 --- a/public/app/core/components/org_switcher.ts +++ b/public/app/core/components/org_switcher.ts @@ -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 = ` + x ); diff --git a/public/app/features/org/state/actions.ts b/public/app/features/org/state/actions.ts index 52793698a45..fc8742d1222 100644 --- a/public/app/features/org/state/actions.ts +++ b/public/app/features/org/state/actions.ts @@ -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 = ThunkAction; - 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 { +export function loadOrganization(): ThunkResult { return async dispatch => { const organizationResponse = await getBackendSrv().get('/api/org'); dispatch(organizationLoaded(organizationResponse)); @@ -40,7 +37,7 @@ export function loadOrganization(): ThunkResult { }; } -export function updateOrganization() { +export function updateOrganization(): ThunkResult { return async (dispatch, getStore) => { const organization = getStore().organization.organization; diff --git a/public/app/features/panel/panel_ctrl.ts b/public/app/features/panel/panel_ctrl.ts index e81312aa0de..cf110cdc705 100644 --- a/public/app/features/panel/panel_ctrl.ts +++ b/public/app/features/panel/panel_ctrl.ts @@ -60,7 +60,7 @@ export class PanelCtrl { } renderingCompleted() { - profiler.renderingCompleted(this.panel.id); + profiler.renderingCompleted(); } refresh() { diff --git a/public/app/plugins/datasource/prometheus/datasource.ts b/public/app/plugins/datasource/prometheus/datasource.ts index c80c30fc682..1bd2ffb5d06 100644 --- a/public/app/plugins/datasource/prometheus/datasource.ts +++ b/public/app/plugins/datasource/prometheus/datasource.ts @@ -137,7 +137,7 @@ export class PrometheusDatasource extends DataSourceApi return escapedValues.join('|'); } - targetContainsTemplate(target) { + targetContainsTemplate(target: PromQuery) { return this.templateSrv.variableExists(target.expr); } diff --git a/public/app/types/alerting.ts b/public/app/types/alerting.ts index c987c2d38ed..26516a052ab 100644 --- a/public/app/types/alerting.ts +++ b/public/app/types/alerting.ts @@ -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 { diff --git a/scripts/ci-frontend-metrics.sh b/scripts/ci-frontend-metrics.sh index e1bcc3a0031..c39cf7cf7da 100755 --- a/scripts/ci-frontend-metrics.sh +++ b/scripts/ci-frontend-metrics.sh @@ -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 diff --git a/yarn.lock b/yarn.lock index 624f08d556b..d78a984dd92 100644 --- a/yarn.lock +++ b/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==