More TS conversions

Signed-off-by: Julius Volz <julius.volz@gmail.com>
This commit is contained in:
Julius Volz 2019-02-14 22:24:22 +01:00
parent 50c0bb0112
commit 5764b90fa0
7 changed files with 95 additions and 69 deletions

19
package-lock.json generated
View file

@ -938,6 +938,14 @@
"resolved": "https://registry.npmjs.org/@types/jest-diff/-/jest-diff-20.0.1.tgz",
"integrity": "sha512-yALhelO3i0hqZwhjtcr6dYyaLoCHbAMshwtj6cGxTvHZAKXHsYGdff6E8EPw3xLKY0ELUTQ69Q1rQiJENnccMA=="
},
"@types/jquery": {
"version": "3.3.29",
"resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.3.29.tgz",
"integrity": "sha512-FhJvBninYD36v3k6c+bVk1DSZwh7B5Dpb/Pyk3HKVsiohn0nhbefZZ+3JXbWQhFyt0MxSl2jRDdGQPHeOHFXrQ==",
"requires": {
"@types/sizzle": "*"
}
},
"@types/node": {
"version": "11.9.3",
"resolved": "https://registry.npmjs.org/@types/node/-/node-11.9.3.tgz",
@ -980,6 +988,11 @@
"popper.js": "^1.14.1"
}
},
"@types/sizzle": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.2.tgz",
"integrity": "sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg=="
},
"@types/tapable": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.2.tgz",
@ -6474,9 +6487,9 @@
"integrity": "sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ=="
},
"handlebars": {
"version": "4.0.12",
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.12.tgz",
"integrity": "sha512-RhmTekP+FZL+XNhwS1Wf+bTTZpdLougwt5pcgA1tuz6Jcx0fpH/7z0qd71RKnZHBCxIRBHfBOnio4gViPemNzA==",
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.0.tgz",
"integrity": "sha512-l2jRuU1NAWK6AW5qqcTATWQJvNPEwkM7NEKSiv/gqOsoSQbVoWyqVEY5GS+XPQ88zLNmqASRpzfdm8d79hJS+w==",
"requires": {
"async": "^2.5.0",
"optimist": "^0.6.1",

View file

@ -7,6 +7,7 @@
"@fortawesome/free-solid-svg-icons": "^5.7.1",
"@fortawesome/react-fontawesome": "^0.1.4",
"@types/jest": "^24.0.4",
"@types/jquery": "^3.3.29",
"@types/node": "^11.9.3",
"@types/react": "^16.8.2",
"@types/react-dom": "^16.8.0",

View file

@ -1,3 +1,4 @@
import $ from 'jquery';
import React, { Component } from 'react';
import {
Button,
@ -7,7 +8,7 @@ import {
Input,
} from 'reactstrap';
import Downshift from 'downshift';
import Downshift, { ChildrenFunction, ControllerStateAndHelpers, DownshiftInterface } from 'downshift';
import fuzzy from 'fuzzy';
import { library } from '@fortawesome/fontawesome-svg-core';
@ -16,32 +17,26 @@ import { faSearch, faSpinner } from '@fortawesome/free-solid-svg-icons';
library.add(faSearch, faSpinner);
class ExpressionInput extends Component {
handleKeyPress = (event) => {
interface ExpressionInputProps {
value: string;
metricNames: string[];
onChange: (expr: string) => void;
executeQuery: () => void;
loading: boolean;
}
class ExpressionInput extends Component<ExpressionInputProps> {
prevNoMatchValue: string | null = null;
exprInputRef: HTMLInputElement | null = null;
handleKeyPress = (event: React.KeyboardEvent<HTMLInputElement>) => {
if (event.key === 'Enter' && !event.shiftKey) {
this.props.executeQuery();
event.preventDefault();
}
}
stateReducer = (state, changes) => {
return changes;
// // TODO: Remove this whole function if I don't notice any odd behavior without it.
// // I don't remember why I had to add this and currently things seem fine without it.
// switch (changes.type) {
// case Downshift.stateChangeTypes.keyDownEnter:
// case Downshift.stateChangeTypes.clickItem:
// case Downshift.stateChangeTypes.changeInput:
// return {
// ...changes,
// selectedItem: changes.inputValue,
// };
// default:
// return changes;
// }
}
renderAutosuggest = (downshift) => {
renderAutosuggest = (downshift: any) => {
if (this.prevNoMatchValue && downshift.inputValue.includes(this.prevNoMatchValue)) {
// TODO: Is this still correct with fuzzy?
return null;
@ -90,7 +85,7 @@ class ExpressionInput extends Component {
}
componentDidMount() {
const $exprInput = window.$(this.exprInputRef);
const $exprInput = $(this.exprInputRef as any)
$exprInput.on('input', () => {
const el = $exprInput.get(0);
const offset = el.offsetHeight - el.clientHeight;
@ -105,7 +100,7 @@ class ExpressionInput extends Component {
onInputValueChange={this.props.onChange}
selectedItem={this.props.value}
>
{downshift => (
{(downshift) => (
<div>
<InputGroup className="expression-input">
<InputGroupAddon addonType="prepend">
@ -117,19 +112,18 @@ class ExpressionInput extends Component {
<Input
autoFocus
type="textarea"
rows={1}
rows="1"
onKeyPress={this.handleKeyPress}
placeholder="Expression (press Shift+Enter for newlines)"
innerRef={ref => this.exprInputRef = ref}
//onChange={selection => alert(`You selected ${selection}`)}
{...downshift.getInputProps({
onKeyDown: event => {
onKeyDown: (event: React.KeyboardEvent): void => {
switch (event.key) {
case 'Home':
case 'End':
// We want to be able to jump to the beginning/end of the input field.
// By default, Downshift otherwise jumps to the first/last suggestion item instead.
event.nativeEvent.preventDownshiftDefault = true;
(event.nativeEvent as any).preventDownshiftDefault = true;
break;
case 'Enter':
downshift.closeMenu();
@ -137,7 +131,7 @@ class ExpressionInput extends Component {
default:
}
}
})}
} as any)}
/>
<InputGroupAddon addonType="append">
<Button className="execute-btn" color="primary" onClick={this.props.executeQuery}>Execute</Button>

View file

@ -21,7 +21,7 @@ import {
faChartLine,
} from '@fortawesome/free-solid-svg-icons';
import TimeInput from './TimeInput.js';
import TimeInput from './TimeInput';
library.add(
faPlus,
@ -30,16 +30,23 @@ library.add(
faChartLine,
);
class GraphControls extends Component {
constructor(props) {
super(props);
interface GraphControlsProps {
range: number;
endTime: number | null;
resolution: number | null;
stacked: boolean;
this.rangeRef = React.createRef();
this.endTimeRef = React.createRef();
this.resolutionRef = React.createRef();
}
onChangeRange: (range: number | null) => void;
onChangeEndTime: (endTime: number | null) => void;
onChangeResolution: (resolution: number | null) => void;
onChangeStacking: (stacked: boolean) => void;
}
rangeUnits = {
class GraphControls extends Component<GraphControlsProps> {
private rangeRef = React.createRef<HTMLInputElement>();
private resolutionRef = React.createRef<HTMLInputElement>();
rangeUnits: {[unit: string]: number} = {
'y': 60 * 60 * 24 * 365,
'w': 60 * 60 * 24 * 7,
'd': 60 * 60 * 24,
@ -49,22 +56,38 @@ class GraphControls extends Component {
}
rangeSteps = [
'1s', '10s', '1m', '5m', '15m', '30m', '1h', '2h', '6h', '12h', '1d', '2d',
'1w', '2w', '4w', '8w', '1y', '2y'
1,
10,
60,
5*60,
15*60,
30*60,
60*60,
2*60*60,
6*60*60,
12*60*60,
24*60*60,
48*60*60,
7*24*60*60,
14*24*60*60,
28*24*60*60,
56*24*60*60,
365*24*60*60,
730*24*60*60,
]
parseRange(rangeText) {
var rangeRE = new RegExp('^([0-9]+)([ywdhms]+)$');
var matches = rangeText.match(rangeRE);
parseRange(rangeText: string): number | null {
const rangeRE = new RegExp('^([0-9]+)([ywdhms]+)$');
const matches = rangeText.match(rangeRE);
if (!matches || matches.length !== 3) {
return null;
}
var value = parseInt(matches[1]);
var unit = matches[2];
const value = parseInt(matches[1]);
const unit = matches[2];
return value * this.rangeUnits[unit];
}
formatRange(range) {
formatRange(range: number): string {
for (let unit of Object.keys(this.rangeUnits)) {
if (range % this.rangeUnits[unit] === 0) {
return (range / this.rangeUnits[unit]) + unit;
@ -73,36 +96,34 @@ class GraphControls extends Component {
return range + 's';
}
onChangeRangeInput = (rangeText) => {
onChangeRangeInput = (rangeText: string): void => {
const range = this.parseRange(rangeText);
if (range === null) {
this.changeRangeInput(this.formatRange(this.props.range));
this.changeRangeInput(this.props.range);
} else {
this.props.onChangeRange(this.parseRange(rangeText));
}
}
changeRangeInput = (rangeText) => {
this.rangeRef.current.value = rangeText;
changeRangeInput = (range: number): void => {
this.rangeRef.current!.value = this.formatRange(range);
}
increaseRange = () => {
increaseRange = (): void => {
for (let range of this.rangeSteps) {
let rangeSeconds = this.parseRange(range);
if (this.props.range < rangeSeconds) {
if (this.props.range < range) {
this.changeRangeInput(range);
this.props.onChangeRange(rangeSeconds);
this.props.onChangeRange(range);
return;
}
}
}
decreaseRange = () => {
decreaseRange = (): void => {
for (let range of this.rangeSteps.slice().reverse()) {
let rangeSeconds = this.parseRange(range);
if (this.props.range > rangeSeconds) {
if (this.props.range > range) {
this.changeRangeInput(range);
this.props.onChangeRange(rangeSeconds);
this.props.onChangeRange(range);
return;
}
}
@ -119,7 +140,7 @@ class GraphControls extends Component {
<Input
defaultValue={this.formatRange(this.props.range)}
innerRef={this.rangeRef}
onBlur={() => this.onChangeRangeInput(this.rangeRef.current.value)}
onBlur={() => this.onChangeRangeInput(this.rangeRef.current!.value)}
/>
<InputGroupAddon addonType="append">
@ -132,9 +153,9 @@ class GraphControls extends Component {
<Input
placeholder="Res. (s)"
className="resolution-input"
defaultValue={this.props.resolution !== null ? this.props.resolution : ''}
defaultValue={this.props.resolution !== null ? this.props.resolution.toString() : ''}
innerRef={this.resolutionRef}
onBlur={() => this.props.onChangeResolution(parseInt(this.resolutionRef.current.value))}
onBlur={() => this.props.onChangeResolution(parseInt(this.resolutionRef.current!.value))}
bsSize="sm"
/>

View file

@ -35,8 +35,6 @@ class Panel extends Component {
error: null,
stats: null,
};
this.handleExpressionChange = this.handleExpressionChange.bind(this);
}
componentDidUpdate(prevProps, prevState) {
@ -133,8 +131,7 @@ class Panel extends Component {
});
}
handleExpressionChange(expr) {
//this.setState({expr: event.target.value});
handleExpressionChange = (expr) => {
this.setState({expr: expr});
}

View file

@ -14,9 +14,9 @@ interface PanelListState {
}
class PanelList extends Component<any, PanelListState> {
key: number;
private key: number;
constructor(props: []) {
constructor(props: any) {
super(props);
this.state = {