mirror of
https://github.com/prometheus/prometheus.git
synced 2025-03-05 20:59:13 -08:00
* Added 16w and 26w time range steps Signed-off-by: Levi Harrison <git@leviharrison.dev> * Fixed indentation Signed-off-by: Levi Harrison <git@leviharrison.dev>
156 lines
4.7 KiB
TypeScript
156 lines
4.7 KiB
TypeScript
import React, { Component } from 'react';
|
|
import { Button, ButtonGroup, Form, InputGroup, InputGroupAddon, Input } from 'reactstrap';
|
|
|
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
import { faPlus, faMinus, faChartArea, faChartLine } from '@fortawesome/free-solid-svg-icons';
|
|
|
|
import TimeInput from './TimeInput';
|
|
import { parseDuration, formatDuration } from '../../utils';
|
|
|
|
interface GraphControlsProps {
|
|
range: number;
|
|
endTime: number | null;
|
|
useLocalTime: boolean;
|
|
resolution: number | null;
|
|
stacked: boolean;
|
|
|
|
onChangeRange: (range: number) => void;
|
|
onChangeEndTime: (endTime: number | null) => void;
|
|
onChangeResolution: (resolution: number | null) => void;
|
|
onChangeStacking: (stacked: boolean) => void;
|
|
}
|
|
|
|
class GraphControls extends Component<GraphControlsProps> {
|
|
private rangeRef = React.createRef<HTMLInputElement>();
|
|
private resolutionRef = React.createRef<HTMLInputElement>();
|
|
|
|
rangeSteps = [
|
|
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,
|
|
112 * 24 * 60 * 60,
|
|
182 * 24 * 60 * 60,
|
|
365 * 24 * 60 * 60,
|
|
730 * 24 * 60 * 60,
|
|
].map(s => s * 1000);
|
|
|
|
onChangeRangeInput = (rangeText: string): void => {
|
|
const range = parseDuration(rangeText);
|
|
if (range === null) {
|
|
this.changeRangeInput(this.props.range);
|
|
} else {
|
|
this.props.onChangeRange(range);
|
|
}
|
|
};
|
|
|
|
changeRangeInput = (range: number): void => {
|
|
this.rangeRef.current!.value = formatDuration(range);
|
|
};
|
|
|
|
increaseRange = (): void => {
|
|
for (const range of this.rangeSteps) {
|
|
if (this.props.range < range) {
|
|
this.changeRangeInput(range);
|
|
this.props.onChangeRange(range);
|
|
return;
|
|
}
|
|
}
|
|
};
|
|
|
|
decreaseRange = (): void => {
|
|
for (const range of this.rangeSteps.slice().reverse()) {
|
|
if (this.props.range > range) {
|
|
this.changeRangeInput(range);
|
|
this.props.onChangeRange(range);
|
|
return;
|
|
}
|
|
}
|
|
};
|
|
|
|
componentDidUpdate(prevProps: GraphControlsProps) {
|
|
if (prevProps.range !== this.props.range) {
|
|
this.changeRangeInput(this.props.range);
|
|
}
|
|
if (prevProps.resolution !== this.props.resolution) {
|
|
this.resolutionRef.current!.value = this.props.resolution !== null ? this.props.resolution.toString() : '';
|
|
}
|
|
}
|
|
|
|
render() {
|
|
return (
|
|
<Form inline className="graph-controls" onSubmit={e => e.preventDefault()}>
|
|
<InputGroup className="range-input" size="sm">
|
|
<InputGroupAddon addonType="prepend">
|
|
<Button title="Decrease range" onClick={this.decreaseRange}>
|
|
<FontAwesomeIcon icon={faMinus} fixedWidth />
|
|
</Button>
|
|
</InputGroupAddon>
|
|
|
|
<Input
|
|
defaultValue={formatDuration(this.props.range)}
|
|
innerRef={this.rangeRef}
|
|
onBlur={() => this.onChangeRangeInput(this.rangeRef.current!.value)}
|
|
onKeyDown={(e: React.KeyboardEvent<HTMLInputElement>) =>
|
|
e.key === 'Enter' && this.onChangeRangeInput(this.rangeRef.current!.value)
|
|
}
|
|
/>
|
|
|
|
<InputGroupAddon addonType="append">
|
|
<Button title="Increase range" onClick={this.increaseRange}>
|
|
<FontAwesomeIcon icon={faPlus} fixedWidth />
|
|
</Button>
|
|
</InputGroupAddon>
|
|
</InputGroup>
|
|
|
|
<TimeInput
|
|
time={this.props.endTime}
|
|
useLocalTime={this.props.useLocalTime}
|
|
range={this.props.range}
|
|
placeholder="End time"
|
|
onChangeTime={this.props.onChangeEndTime}
|
|
/>
|
|
|
|
<Input
|
|
placeholder="Res. (s)"
|
|
className="resolution-input"
|
|
defaultValue={this.props.resolution !== null ? this.props.resolution.toString() : ''}
|
|
innerRef={this.resolutionRef}
|
|
onBlur={() => {
|
|
const res = parseInt(this.resolutionRef.current!.value);
|
|
this.props.onChangeResolution(res ? res : null);
|
|
}}
|
|
bsSize="sm"
|
|
/>
|
|
|
|
<ButtonGroup className="stacked-input" size="sm">
|
|
<Button
|
|
title="Show unstacked line graph"
|
|
onClick={() => this.props.onChangeStacking(false)}
|
|
active={!this.props.stacked}
|
|
>
|
|
<FontAwesomeIcon icon={faChartLine} fixedWidth />
|
|
</Button>
|
|
<Button title="Show stacked graph" onClick={() => this.props.onChangeStacking(true)} active={this.props.stacked}>
|
|
<FontAwesomeIcon icon={faChartArea} fixedWidth />
|
|
</Button>
|
|
</ButtonGroup>
|
|
</Form>
|
|
);
|
|
}
|
|
}
|
|
|
|
export default GraphControls;
|