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", "resolved": "https://registry.npmjs.org/@types/jest-diff/-/jest-diff-20.0.1.tgz",
"integrity": "sha512-yALhelO3i0hqZwhjtcr6dYyaLoCHbAMshwtj6cGxTvHZAKXHsYGdff6E8EPw3xLKY0ELUTQ69Q1rQiJENnccMA==" "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": { "@types/node": {
"version": "11.9.3", "version": "11.9.3",
"resolved": "https://registry.npmjs.org/@types/node/-/node-11.9.3.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-11.9.3.tgz",
@ -980,6 +988,11 @@
"popper.js": "^1.14.1" "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": { "@types/tapable": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.2.tgz", "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.2.tgz",
@ -6474,9 +6487,9 @@
"integrity": "sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ==" "integrity": "sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ=="
}, },
"handlebars": { "handlebars": {
"version": "4.0.12", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.12.tgz", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.0.tgz",
"integrity": "sha512-RhmTekP+FZL+XNhwS1Wf+bTTZpdLougwt5pcgA1tuz6Jcx0fpH/7z0qd71RKnZHBCxIRBHfBOnio4gViPemNzA==", "integrity": "sha512-l2jRuU1NAWK6AW5qqcTATWQJvNPEwkM7NEKSiv/gqOsoSQbVoWyqVEY5GS+XPQ88zLNmqASRpzfdm8d79hJS+w==",
"requires": { "requires": {
"async": "^2.5.0", "async": "^2.5.0",
"optimist": "^0.6.1", "optimist": "^0.6.1",

View file

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

View file

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

View file

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

View file

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

View file

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