Work on history functionality

Signed-off-by: Julius Volz <julius.volz@gmail.com>
This commit is contained in:
Julius Volz 2019-02-17 14:43:11 +01:00
parent f3b9fd5989
commit 38259bc45e
5 changed files with 42 additions and 29 deletions

View file

@ -35,7 +35,7 @@ interface GraphControlsProps {
onChangeRange: (range: number) => void; onChangeRange: (range: number) => void;
onChangeEndTime: (endTime: number | null) => void; onChangeEndTime: (endTime: number | null) => void;
onChangeResolution: (resolution: number) => void; onChangeResolution: (resolution: number | null) => void;
onChangeStacking: (stacked: boolean) => void; onChangeStacking: (stacked: boolean) => void;
} }
@ -97,6 +97,15 @@ class GraphControls extends Component<GraphControlsProps> {
} }
} }
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() { render() {
return ( return (
<Form inline className="graph-controls" onSubmit={e => e.preventDefault()}> <Form inline className="graph-controls" onSubmit={e => e.preventDefault()}>
@ -128,7 +137,10 @@ class GraphControls extends Component<GraphControlsProps> {
className="resolution-input" className="resolution-input"
defaultValue={this.props.resolution !== null ? this.props.resolution.toString() : ''} 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={() => {
const res = parseInt(this.resolutionRef.current!.value);
this.props.onChangeResolution(res ? res : null);
}}
bsSize="sm" bsSize="sm"
/> />

View file

@ -201,13 +201,9 @@ class Panel extends Component<PanelProps, PanelState> {
this.setOptions({endTime: endTime}); this.setOptions({endTime: endTime});
} }
handleChangeResolution = (resolution: number) => { handleChangeResolution = (resolution: number | null) => {
// TODO: Where should we validate domain model constraints? In the parent's
// change handler like here, or in the calling component?
if (resolution > 0) {
this.setOptions({resolution: resolution}); this.setOptions({resolution: resolution});
} }
}
handleChangeStacking = (stacked: boolean) => { handleChangeStacking = (stacked: boolean) => {
this.setOptions({stacked: stacked}); this.setOptions({stacked: stacked});

View file

@ -21,12 +21,7 @@ class PanelList extends Component<any, PanelListState> {
constructor(props: any) { constructor(props: any) {
super(props); super(props);
const urlPanels = decodePanelOptionsFromQueryString(window.location.search).map((opts: PanelOptions) => { const urlPanels = decodePanelOptionsFromQueryString(window.location.search);
return {
key: this.getKey(),
options: opts,
};
});
this.state = { this.state = {
panels: urlPanels.length !== 0 ? urlPanels : [ panels: urlPanels.length !== 0 ? urlPanels : [
@ -71,6 +66,14 @@ class PanelList extends Component<any, PanelListState> {
} }
}) })
.catch(error => this.setState({ timeDriftError: error.message })); .catch(error => this.setState({ timeDriftError: error.message }));
window.onpopstate = () => {
console.log("POPSTATE");
const panels = decodePanelOptionsFromQueryString(window.location.search);
if (panels.length !== 0) {
this.setState({panels: panels});
}
}
} }
getKey(): string { getKey(): string {
@ -87,12 +90,14 @@ class PanelList extends Component<any, PanelListState> {
} }
return p; return p;
}); });
console.log("UPDATE OP", key, opts);
this.setState({panels: newPanels}, this.updateURL) this.setState({panels: newPanels}, this.updateURL)
} }
updateURL(): void { updateURL(): void {
console.log("UPDATE");
const query = encodePanelOptionsToQueryString(this.state.panels); const query = encodePanelOptionsToQueryString(this.state.panels);
history.pushState({}, '', 'graph' + query); history.pushState({}, '', query);
} }
addPanel = (): void => { addPanel = (): void => {

View file

@ -50,18 +50,15 @@ class TimeInput extends Component<TimeInputProps> {
increaseTime = (): void => { increaseTime = (): void => {
const time = this.getBaseTime() + this.props.range*1000/2; const time = this.getBaseTime() + this.props.range*1000/2;
this.props.onChangeTime(time); this.props.onChangeTime(time);
this.$time.datetimepicker('date', moment(time));
} }
decreaseTime = (): void => { decreaseTime = (): void => {
const time = this.getBaseTime() - this.props.range*1000/2; const time = this.getBaseTime() - this.props.range*1000/2;
this.props.onChangeTime(time); this.props.onChangeTime(time);
this.$time.datetimepicker('date', moment(time));
} }
clearTime = (): void => { clearTime = (): void => {
this.props.onChangeTime(null); this.props.onChangeTime(null);
this.$time.datetimepicker('date', null);
} }
componentDidMount() { componentDidMount() {
@ -85,9 +82,7 @@ class TimeInput extends Component<TimeInputProps> {
this.$time.on('change.datetimepicker', (e: any) => { this.$time.on('change.datetimepicker', (e: any) => {
if (e.date) { if (e.date) {
this.props.onChangeTime(e.date); this.props.onChangeTime(e.date.valueOf());
} else {
this.$time.datetimepicker('date', e.target.value);
} }
}); });
} }
@ -96,6 +91,11 @@ class TimeInput extends Component<TimeInputProps> {
this.$time.datetimepicker('destroy'); this.$time.datetimepicker('destroy');
} }
componentDidUpdate() {
console.log(this.props);
this.$time.datetimepicker('date', this.props.time ? moment(this.props.time) : null);
}
render() { render() {
return ( return (
<InputGroup className="time-input" size="sm"> <InputGroup className="time-input" size="sm">

View file

@ -1,7 +1,7 @@
import { parseRange, parseTime, formatRange, formatTime } from './timeFormat'; import { parseRange, parseTime, formatRange, formatTime } from './timeFormat';
import { PanelOptions, PanelType, PanelDefaultOptions } from '../Panel'; import { PanelOptions, PanelType, PanelDefaultOptions } from '../Panel';
export function decodePanelOptionsFromQueryString(query: string): PanelOptions[] { export function decodePanelOptionsFromQueryString(query: string): {key: string, options: PanelOptions}[] {
if (query === '') { if (query === '') {
return []; return [];
} }
@ -21,12 +21,12 @@ interface IncompletePanelOptions {
stacked?: boolean; stacked?: boolean;
} }
function parseParams(params: string[]): PanelOptions[] { function parseParams(params: string[]): {key: string, options: PanelOptions}[] {
const sortedParams = params.filter((p) => { const sortedParams = params.filter((p) => {
return paramFormat.test(p); return paramFormat.test(p);
}).sort(); }).sort();
let panelOpts: PanelOptions[] = []; let panelOpts: {key: string, options: PanelOptions}[] = [];
let key = 0; let key = 0;
let options: IncompletePanelOptions = {}; let options: IncompletePanelOptions = {};
@ -35,8 +35,8 @@ function parseParams(params: string[]): PanelOptions[] {
if (!p.startsWith(prefix)) { if (!p.startsWith(prefix)) {
panelOpts.push({ panelOpts.push({
...PanelDefaultOptions, key: key.toString(),
...options, options: {...PanelDefaultOptions, ...options},
}); });
options = {}; options = {};
key++; key++;
@ -45,8 +45,8 @@ function parseParams(params: string[]): PanelOptions[] {
addParam(options, p.substring(prefix.length)); addParam(options, p.substring(prefix.length));
} }
panelOpts.push({ panelOpts.push({
...PanelDefaultOptions, key: key.toString(),
...options, options: {...PanelDefaultOptions, ...options},
}); });
return panelOpts; return panelOpts;
@ -85,7 +85,7 @@ function addParam(opts: IncompletePanelOptions, param: string): void {
break; break;
case 'step_input': case 'step_input':
const res = parseInt(val) const res = parseInt(val);
if (res > 0) { if (res > 0) {
opts.resolution = res; opts.resolution = res;
} }