mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Chore: Upgrade typescript and related packages (#27316)
* Chore: Upgrade typescript and related packages Closes #27115 * Apply suggestions from code review Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com> * fixes some tests * Fix failing tests * Apply suggestions from code review Co-authored-by: Dominik Prokop <dominik.prokop@grafana.com> Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com> Co-authored-by: Dominik Prokop <dominik.prokop@grafana.com>
This commit is contained in:
parent
3b8701a35d
commit
d322417217
13
package.json
13
package.json
@ -119,8 +119,9 @@
|
||||
"@types/testing-library__jest-dom": "^5.9.2",
|
||||
"@types/testing-library__react-hooks": "^3.2.0",
|
||||
"@types/tinycolor2": "1.4.2",
|
||||
"@typescript-eslint/eslint-plugin": "3.6.0",
|
||||
"@typescript-eslint/parser": "3.6.0",
|
||||
"@typescript-eslint/eslint-plugin": "4.0.1",
|
||||
"@typescript-eslint/parser": "4.0.1",
|
||||
"angular-mocks": "1.6.6",
|
||||
"autoprefixer": "9.7.4",
|
||||
"axios": "0.19.2",
|
||||
"babel-core": "7.0.0-bridge.0",
|
||||
@ -162,7 +163,7 @@
|
||||
"html-webpack-harddisk-plugin": "1.0.1",
|
||||
"html-webpack-plugin": "3.2.0",
|
||||
"husky": "4.2.1",
|
||||
"jest": "26.0.0",
|
||||
"jest": "26.4.2",
|
||||
"jest-canvas-mock": "2.2.0",
|
||||
"jest-date-mock": "1.0.8",
|
||||
"lerna": "^3.20.2",
|
||||
@ -192,10 +193,10 @@
|
||||
"sinon": "8.1.1",
|
||||
"style-loader": "1.1.3",
|
||||
"terser-webpack-plugin": "2.3.5",
|
||||
"ts-jest": "26.1.0",
|
||||
"ts-jest": "26.3.0",
|
||||
"ts-node": "8.8.1",
|
||||
"tslib": "1.10.0",
|
||||
"typescript": "3.9.3",
|
||||
"tslib": "2.0.1",
|
||||
"typescript": "4.0.2",
|
||||
"webpack": "4.41.5",
|
||||
"webpack-bundle-analyzer": "3.6.0",
|
||||
"webpack-cleanup-plugin": "0.5.1",
|
||||
|
@ -49,6 +49,6 @@
|
||||
"rollup-plugin-typescript2": "0.26.0",
|
||||
"rollup-plugin-visualizer": "3.3.1",
|
||||
"sinon": "8.1.1",
|
||||
"typescript": "3.9.3"
|
||||
"typescript": "4.0.2"
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +43,7 @@
|
||||
"@grafana/tsconfig": "^1.0.0-rc1",
|
||||
"commander": "5.0.0",
|
||||
"execa": "4.0.0",
|
||||
"typescript": "3.9.3",
|
||||
"typescript": "4.0.2",
|
||||
"yaml": "^1.8.3"
|
||||
}
|
||||
}
|
||||
|
@ -54,7 +54,7 @@
|
||||
"execa": "4.0.0",
|
||||
"resolve-as-bin": "2.1.0",
|
||||
"ts-loader": "6.2.1",
|
||||
"typescript": "3.9.3",
|
||||
"typescript": "4.0.2",
|
||||
"yaml": "^1.8.3"
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +41,7 @@
|
||||
"rollup-plugin-terser": "5.3.0",
|
||||
"rollup-plugin-typescript2": "0.26.0",
|
||||
"rollup-plugin-visualizer": "3.3.1",
|
||||
"typescript": "3.9.3"
|
||||
"typescript": "4.0.2"
|
||||
},
|
||||
"types": "src/index.ts"
|
||||
}
|
||||
|
@ -47,8 +47,8 @@
|
||||
"@types/semver": "^6.0.0",
|
||||
"@types/tmp": "^0.1.0",
|
||||
"@types/webpack": "4.41.7",
|
||||
"@typescript-eslint/eslint-plugin": "3.6.0",
|
||||
"@typescript-eslint/parser": "3.6.0",
|
||||
"@typescript-eslint/eslint-plugin": "4.0.1",
|
||||
"@typescript-eslint/parser": "4.0.1",
|
||||
"axios": "0.19.2",
|
||||
"babel-jest": "24.8.0",
|
||||
"babel-loader": "8.1.0",
|
||||
@ -102,11 +102,11 @@
|
||||
"simple-git": "^1.132.0",
|
||||
"style-loader": "^0.23.1",
|
||||
"terser-webpack-plugin": "^2.3.4",
|
||||
"ts-jest": "24.1.0",
|
||||
"ts-jest": "26.3.0",
|
||||
"ts-loader": "6.2.1",
|
||||
"ts-node": "8.8.1",
|
||||
"tslib": "1.10.0",
|
||||
"typescript": "3.9.3",
|
||||
"tslib": "2.0.1",
|
||||
"typescript": "4.0.2",
|
||||
"url-loader": "^2.0.1",
|
||||
"webpack": "4.41.5"
|
||||
},
|
||||
|
@ -107,7 +107,7 @@
|
||||
"rollup-plugin-visualizer": "3.3.1",
|
||||
"storybook-dark-mode": "0.6.1",
|
||||
"ts-loader": "6.2.1",
|
||||
"typescript": "3.9.3"
|
||||
"typescript": "4.0.2"
|
||||
},
|
||||
"types": "src/index.ts"
|
||||
}
|
||||
|
@ -188,7 +188,7 @@ export const ContextMenu: React.FC<ContextMenuProps> = React.memo(({ x, y, onClo
|
||||
renderItem={(item, index) => {
|
||||
return (
|
||||
<>
|
||||
<ContextMenuGroup group={item} onClick={onClose} />
|
||||
<ContextMenuGroupComponent group={item} onClick={onClose} />
|
||||
</>
|
||||
);
|
||||
}}
|
||||
@ -207,7 +207,7 @@ interface ContextMenuItemProps {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const ContextMenuItem: React.FC<ContextMenuItemProps> = React.memo(
|
||||
const ContextMenuItemComponent: React.FC<ContextMenuItemProps> = React.memo(
|
||||
({ url, icon, label, target, onClick, className }) => {
|
||||
const theme = useContext(ThemeContext);
|
||||
const styles = getContextMenuStyles(theme);
|
||||
@ -235,7 +235,7 @@ interface ContextMenuGroupProps {
|
||||
onClick?: () => void; // Used with 'onClose'
|
||||
}
|
||||
|
||||
const ContextMenuGroup: React.FC<ContextMenuGroupProps> = ({ group, onClick }) => {
|
||||
const ContextMenuGroupComponent: React.FC<ContextMenuGroupProps> = ({ group, onClick }) => {
|
||||
const theme = useContext(ThemeContext);
|
||||
const styles = getContextMenuStyles(theme);
|
||||
|
||||
@ -250,7 +250,7 @@ const ContextMenuGroup: React.FC<ContextMenuGroupProps> = ({ group, onClick }) =
|
||||
items={group.items || []}
|
||||
renderItem={item => {
|
||||
return (
|
||||
<ContextMenuItem
|
||||
<ContextMenuItemComponent
|
||||
url={item.url}
|
||||
label={item.label}
|
||||
target={item.target}
|
||||
|
@ -5,13 +5,13 @@ import { stylesFactory, useTheme } from '../../themes';
|
||||
import { Badge, BadgeProps } from '../Badge/Badge';
|
||||
import { css } from 'emotion';
|
||||
|
||||
interface FeatureInfoBox extends Omit<InfoBoxProps, 'branded' | 'title' | 'urlTitle'> {
|
||||
interface FeatureInfoBoxProps extends Omit<InfoBoxProps, 'branded' | 'title' | 'urlTitle'> {
|
||||
title: string;
|
||||
featureState?: FeatureState;
|
||||
}
|
||||
|
||||
export const FeatureInfoBox = React.memo(
|
||||
React.forwardRef<HTMLDivElement, FeatureInfoBox>(({ title, featureState, ...otherProps }, ref) => {
|
||||
React.forwardRef<HTMLDivElement, FeatureInfoBoxProps>(({ title, featureState, ...otherProps }, ref) => {
|
||||
const theme = useTheme();
|
||||
const styles = getFeatureInfoBoxStyles(theme);
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
"devDependencies": {
|
||||
"enzyme": "^3.8.0",
|
||||
"enzyme-adapter-react-16": "^1.2.0",
|
||||
"typescript": "3.9.3"
|
||||
"typescript": "4.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@grafana/data": "7.3.0-pre.0",
|
||||
|
@ -8,13 +8,13 @@ import appEvents from 'app/core/app_events';
|
||||
import { AppEvents } from '@grafana/data';
|
||||
|
||||
interface SignupDTO {
|
||||
name: string;
|
||||
name?: string;
|
||||
email: string;
|
||||
username: string;
|
||||
orgName?: string;
|
||||
password: string;
|
||||
code: string;
|
||||
confirm: string;
|
||||
confirm?: string;
|
||||
}
|
||||
|
||||
interface ConnectedProps {
|
||||
|
@ -28,6 +28,7 @@ function mockLocationHref(href: string) {
|
||||
search = href.substring(searchPos);
|
||||
}
|
||||
|
||||
//@ts-ignore
|
||||
delete window.location;
|
||||
(window as any).location = {
|
||||
...location,
|
||||
|
@ -80,7 +80,7 @@ export class DashboardModel {
|
||||
// ------------------
|
||||
|
||||
// repeat process cycles
|
||||
iteration: number;
|
||||
iteration?: number;
|
||||
meta: DashboardMeta;
|
||||
events: Emitter;
|
||||
|
||||
|
@ -1,3 +1,11 @@
|
||||
const applyFieldOverridesMock = jest.fn();
|
||||
|
||||
jest.mock('@grafana/data', () => ({
|
||||
__esModule: true,
|
||||
...(jest.requireActual('@grafana/data') as any),
|
||||
applyFieldOverrides: applyFieldOverridesMock,
|
||||
}));
|
||||
|
||||
import { PanelQueryRunner } from './PanelQueryRunner';
|
||||
// Importing this way to be able to spy on grafana/data
|
||||
import * as grafanaData from '@grafana/data';
|
||||
@ -131,6 +139,10 @@ function describeQueryRunnerScenario(description: string, scenarioFn: ScenarioFn
|
||||
}
|
||||
|
||||
describe('PanelQueryRunner', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
describeQueryRunnerScenario('simple scenario', ctx => {
|
||||
it('should set requestId on request', async () => {
|
||||
expect(ctx.queryCalledWith?.requestId).toBe('Q100');
|
||||
@ -211,14 +223,12 @@ describe('PanelQueryRunner', () => {
|
||||
'field overrides',
|
||||
ctx => {
|
||||
it('should apply when field override options are set', async () => {
|
||||
const spy = jest.spyOn(grafanaData, 'applyFieldOverrides');
|
||||
|
||||
ctx.runner.getData({ withTransforms: true, withFieldConfig: true }).subscribe({
|
||||
next: (data: PanelData) => {
|
||||
return data;
|
||||
},
|
||||
});
|
||||
expect(spy).toBeCalled();
|
||||
expect(applyFieldOverridesMock).toBeCalled();
|
||||
});
|
||||
},
|
||||
{
|
||||
@ -277,15 +287,13 @@ describe('PanelQueryRunner', () => {
|
||||
});
|
||||
|
||||
it('should not apply field config when applyFieldConfig option is false', async () => {
|
||||
const spy = jest.spyOn(grafanaData, 'applyFieldOverrides');
|
||||
spy.mockClear();
|
||||
ctx.runner.getData({ withFieldConfig: false, withTransforms: true }).subscribe({
|
||||
next: (data: PanelData) => {
|
||||
return data;
|
||||
},
|
||||
});
|
||||
|
||||
expect(spy).not.toBeCalled();
|
||||
expect(applyFieldOverridesMock).not.toBeCalled();
|
||||
});
|
||||
},
|
||||
{
|
||||
@ -322,15 +330,13 @@ describe('PanelQueryRunner', () => {
|
||||
});
|
||||
|
||||
it('should not apply field config when applyFieldConfig option is false', async () => {
|
||||
const spy = jest.spyOn(grafanaData, 'applyFieldOverrides');
|
||||
spy.mockClear();
|
||||
ctx.runner.getData({ withFieldConfig: false, withTransforms: true }).subscribe({
|
||||
next: (data: PanelData) => {
|
||||
return data;
|
||||
},
|
||||
});
|
||||
|
||||
expect(spy).not.toBeCalled();
|
||||
expect(applyFieldOverridesMock).not.toBeCalled();
|
||||
});
|
||||
},
|
||||
{
|
||||
|
@ -44,6 +44,7 @@ const mockWindowLocation = (): [jest.MockInstance<any, any>, () => void] => {
|
||||
|
||||
// JSDom defines window in a way that you cannot tamper with location so this seems to be the only way to change it.
|
||||
// https://github.com/facebook/jest/issues/5124#issuecomment-446659510
|
||||
//@ts-ignore
|
||||
delete window.location;
|
||||
window.location = {} as any;
|
||||
|
||||
|
@ -91,7 +91,7 @@ export const initQueryVariableEditor = (identifier: VariableIdentifier): ThunkRe
|
||||
if (!variable.datasource) {
|
||||
return;
|
||||
}
|
||||
dispatch(changeQueryVariableDataSource(toVariableIdentifier(variable), variable.datasource));
|
||||
await dispatch(changeQueryVariableDataSource(toVariableIdentifier(variable), variable.datasource));
|
||||
};
|
||||
|
||||
export const changeQueryVariableDataSource = (
|
||||
|
@ -35,7 +35,9 @@ export function toVariablePayload<T extends any = undefined>(
|
||||
identifier: VariableIdentifier,
|
||||
data?: T
|
||||
): VariablePayload<T>;
|
||||
// eslint-disable-next-line
|
||||
export function toVariablePayload<T extends any = undefined>(model: VariableModel, data?: T): VariablePayload<T>;
|
||||
// eslint-disable-next-line
|
||||
export function toVariablePayload<T extends any = undefined>(
|
||||
obj: VariableIdentifier | VariableModel,
|
||||
data?: T
|
||||
|
@ -20,7 +20,9 @@ describe('ConfigEditor', () => {
|
||||
|
||||
it('should set defaults', () => {
|
||||
const options = createDefaultConfigOptions();
|
||||
//@ts-ignore
|
||||
delete options.jsonData.esVersion;
|
||||
//@ts-ignore
|
||||
delete options.jsonData.timeField;
|
||||
delete options.jsonData.maxConcurrentShardRequests;
|
||||
|
||||
|
@ -72,7 +72,7 @@ export default class AppInsightsDatasource extends DataSourceWithBackend<AzureMo
|
||||
}
|
||||
|
||||
applyTemplateVariables(target: AzureMonitorQuery, scopedVars: ScopedVars): Record<string, any> {
|
||||
const item = target.appInsights;
|
||||
const item = target.appInsights!;
|
||||
|
||||
const old: any = item;
|
||||
// fix for timeGrainUnit which is a deprecated/removed field name
|
||||
|
@ -16,7 +16,7 @@ export interface AzureMonitorQuery extends DataQuery {
|
||||
|
||||
azureMonitor: AzureMetricQuery;
|
||||
azureLogAnalytics: AzureLogsQuery;
|
||||
appInsights: ApplicationInsightsQuery;
|
||||
appInsights?: ApplicationInsightsQuery;
|
||||
insightsAnalytics: InsightsAnalyticsQuery;
|
||||
}
|
||||
|
||||
@ -57,7 +57,7 @@ export interface AzureMetricQuery {
|
||||
metricDefinition: string;
|
||||
metricNamespace: string;
|
||||
metricName: string;
|
||||
timeGrainUnit: string;
|
||||
timeGrainUnit?: string;
|
||||
timeGrain: string;
|
||||
allowedTimeGrainsMs: number[];
|
||||
aggregation: string;
|
||||
|
@ -46,7 +46,7 @@ export class ConfigEditor extends PureComponent<Props> {
|
||||
onVersionChanged = (selected: SelectableValue<InfluxVersion>) => {
|
||||
const { options, onOptionsChange } = this.props;
|
||||
|
||||
const copy = {
|
||||
const copy: any = {
|
||||
...options,
|
||||
jsonData: {
|
||||
...options.jsonData,
|
||||
|
@ -64,7 +64,7 @@ describe('InfluxLogsQueryField', () => {
|
||||
const wrapper = getInfluxLogsQueryField();
|
||||
// Looks strange but we do async stuff in didMount and this will push the stack at the end of eval loop, effectively
|
||||
// waiting for the didMount to finish.
|
||||
await Promise.resolve();
|
||||
await new Promise(resolve => setImmediate(resolve));
|
||||
wrapper.update();
|
||||
const cascader = wrapper.find(ButtonCascader);
|
||||
expect(cascader.prop('options')).toEqual([
|
||||
|
@ -1,12 +1,11 @@
|
||||
import { mount } from 'enzyme';
|
||||
// @ts-ignore
|
||||
import RCCascader from 'rc-cascader';
|
||||
import React from 'react';
|
||||
import PromQlLanguageProvider, { DEFAULT_LOOKUP_METRICS_THRESHOLD } from '../language_provider';
|
||||
import PromQueryField, { groupMetricsByPrefix, RECORDING_RULES_GROUP } from './PromQueryField';
|
||||
import { ButtonCascader } from '@grafana/ui';
|
||||
import { DataSourceInstanceSettings } from '@grafana/data';
|
||||
import { PromOptions } from '../types';
|
||||
import { fireEvent, render, screen } from '@testing-library/react';
|
||||
|
||||
describe('PromQueryField', () => {
|
||||
beforeAll(() => {
|
||||
@ -21,7 +20,7 @@ describe('PromQueryField', () => {
|
||||
},
|
||||
} as unknown) as DataSourceInstanceSettings<PromOptions>;
|
||||
|
||||
const queryField = mount(
|
||||
const queryField = render(
|
||||
<PromQueryField
|
||||
// @ts-ignore
|
||||
datasource={datasource}
|
||||
@ -32,11 +31,11 @@ describe('PromQueryField', () => {
|
||||
/>
|
||||
);
|
||||
|
||||
expect(queryField.find(ButtonCascader).length).toBe(1);
|
||||
expect(queryField.getAllByRole('button')).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('renders a disabled metrics chooser if lookups are disabled in datasource settings', () => {
|
||||
const queryField = mount(
|
||||
const queryField = render(
|
||||
<PromQueryField
|
||||
// @ts-ignore
|
||||
datasource={{ lookupsDisabled: true }}
|
||||
@ -47,12 +46,8 @@ describe('PromQueryField', () => {
|
||||
/>
|
||||
);
|
||||
|
||||
expect(
|
||||
queryField
|
||||
.find(ButtonCascader)
|
||||
.find('button')
|
||||
.props().disabled
|
||||
).toBe(true);
|
||||
const bcButton = queryField.getByRole('button');
|
||||
expect(bcButton).toBeDisabled();
|
||||
});
|
||||
|
||||
it('refreshes metrics when the data source changes', async () => {
|
||||
@ -68,7 +63,7 @@ describe('PromQueryField', () => {
|
||||
},
|
||||
} as unknown) as PromQlLanguageProvider;
|
||||
|
||||
const queryField = mount(
|
||||
const queryField = render(
|
||||
<PromQueryField
|
||||
// @ts-ignore
|
||||
datasource={{
|
||||
@ -80,29 +75,36 @@ describe('PromQueryField', () => {
|
||||
history={[]}
|
||||
/>
|
||||
);
|
||||
await Promise.resolve();
|
||||
|
||||
const cascader = queryField.find<RCCascader>(RCCascader);
|
||||
cascader.simulate('click');
|
||||
const cascaderNode: HTMLElement = cascader.instance().getPopupDOMNode();
|
||||
|
||||
for (const item of Array.from(cascaderNode.getElementsByTagName('li'))) {
|
||||
expect(metrics.includes(item.innerHTML)).toBe(true);
|
||||
let cascader = await queryField.findByRole('button');
|
||||
fireEvent.keyDown(cascader, { keyCode: 40 });
|
||||
let listNodes = screen.getAllByRole('menuitem');
|
||||
for (const node of listNodes) {
|
||||
expect(metrics).toContain(node.innerHTML);
|
||||
}
|
||||
|
||||
const changedMetrics = ['baz', 'moo'];
|
||||
queryField.setProps({
|
||||
datasource: {
|
||||
languageProvider: {
|
||||
...languageProvider,
|
||||
metrics: changedMetrics,
|
||||
},
|
||||
},
|
||||
});
|
||||
await Promise.resolve();
|
||||
queryField.rerender(
|
||||
<PromQueryField
|
||||
datasource={{
|
||||
//@ts-ignore
|
||||
languageProvider: {
|
||||
...languageProvider,
|
||||
metrics: changedMetrics,
|
||||
},
|
||||
}}
|
||||
query={{ expr: '', refId: '' }}
|
||||
onRunQuery={() => {}}
|
||||
onChange={() => {}}
|
||||
history={[]}
|
||||
/>
|
||||
);
|
||||
|
||||
for (const item of Array.from(cascaderNode.getElementsByTagName('li'))) {
|
||||
expect(changedMetrics.includes(item.innerHTML)).toBe(true);
|
||||
cascader = await queryField.findByRole('button');
|
||||
fireEvent.keyDown(cascader, { keyCode: 40 });
|
||||
listNodes = screen.getAllByRole('menuitem');
|
||||
for (const node of listNodes) {
|
||||
expect(changedMetrics).toContain(node.innerHTML);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user