2
0
mirror of https://github.com/hibiken/asynqmon.git synced 2025-10-26 08:16:10 +08:00

(ui): Add top level shift buttons

This commit is contained in:
Ken Hibino
2021-12-05 16:34:30 -08:00
parent 6046f676d4
commit af43063619

View File

@@ -1,7 +1,8 @@
import React from "react"; import React from "react";
import { connect, ConnectedProps } from "react-redux"; import { connect, ConnectedProps } from "react-redux";
import { makeStyles } from "@material-ui/core/styles"; import { makeStyles } from "@material-ui/core/styles";
import Button from "@material-ui/core/Button"; import Button, { ButtonProps } from "@material-ui/core/Button";
import ButtonGroup from "@material-ui/core/ButtonGroup";
import Popover from "@material-ui/core/Popover"; import Popover from "@material-ui/core/Popover";
import Radio from "@material-ui/core/Radio"; import Radio from "@material-ui/core/Radio";
import RadioGroup from "@material-ui/core/RadioGroup"; import RadioGroup from "@material-ui/core/RadioGroup";
@@ -53,6 +54,12 @@ const useStyles = makeStyles((theme) => ({
endTimeCaption: { endTimeCaption: {
marginRight: theme.spacing(1), marginRight: theme.spacing(1),
}, },
shiftButtons: {
marginLeft: theme.spacing(1),
},
buttonGroupRoot: {
height: 30,
},
endTimeShiftControls: { endTimeShiftControls: {
padding: theme.spacing(1), padding: theme.spacing(1),
display: "flex", display: "flex",
@@ -331,269 +338,311 @@ function MetricsFetchControls(props: Props) {
<Typography variant="caption" className={classes.endTimeCaption}> <Typography variant="caption" className={classes.endTimeCaption}>
{formatTime(props.endTimeSec)} {formatTime(props.endTimeSec)}
</Typography> </Typography>
<Button <div>
aria-describedby={id} <Button
variant="outlined" aria-describedby={id}
color="primary" variant="outlined"
onClick={handleButtonClick} color="primary"
size="small" onClick={handleButtonClick}
classes={{ size="small"
label: classes.buttonLabel, classes={{
}} label: classes.buttonLabel,
> }}
{state.endTimeOption === "real_time" ? "Realtime" : "Historical"}:{" "} >
{state.durationOption === "custom" {state.endTimeOption === "real_time" ? "Realtime" : "Historical"}:{" "}
? state.customDuration {state.durationOption === "custom"
: state.durationOption} ? state.customDuration
</Button> : state.durationOption}
<Popover </Button>
id={id} <Popover
open={open} id={id}
anchorEl={anchorEl} open={open}
onClose={handleClose} anchorEl={anchorEl}
anchorOrigin={{ onClose={handleClose}
vertical: "bottom", anchorOrigin={{
horizontal: "center", vertical: "bottom",
}} horizontal: "center",
transformOrigin={{ }}
vertical: "top", transformOrigin={{
horizontal: "center", vertical: "top",
}} horizontal: "center",
> }}
<div className={classes.endTimeShiftControls}> >
<div className={classes.leftShiftButtons}> <div className={classes.endTimeShiftControls}>
<ShiftButton <div className={classes.leftShiftButtons}>
direction="left" <ShiftButton
text="2h" direction="left"
onClick={shiftBy(-2 * hour)} text="2h"
/> onClick={shiftBy(-2 * hour)}
<ShiftButton dense={true}
direction="left" />
text="1h" <ShiftButton
onClick={shiftBy(-1 * hour)} direction="left"
/> text="1h"
<ShiftButton onClick={shiftBy(-1 * hour)}
direction="left" dense={true}
text="30m" />
onClick={shiftBy(-30 * minute)} <ShiftButton
/> direction="left"
<ShiftButton text="30m"
direction="left" onClick={shiftBy(-30 * minute)}
text="15m" dense={true}
onClick={shiftBy(-15 * minute)} />
/> <ShiftButton
<ShiftButton direction="left"
direction="left" text="15m"
text="5m" onClick={shiftBy(-15 * minute)}
onClick={shiftBy(-5 * minute)} dense={true}
/> />
<ShiftButton
direction="left"
text="5m"
onClick={shiftBy(-5 * minute)}
dense={true}
/>
</div>
<div className={classes.rightShiftButtons}>
<ShiftButton
direction="right"
text="5m"
onClick={shiftBy(5 * minute)}
dense={true}
/>
<ShiftButton
direction="right"
text="15m"
onClick={shiftBy(15 * minute)}
dense={true}
/>
<ShiftButton
direction="right"
text="30m"
onClick={shiftBy(30 * minute)}
dense={true}
/>
<ShiftButton
direction="right"
text="1h"
onClick={shiftBy(1 * hour)}
dense={true}
/>
<ShiftButton
direction="right"
text="2h"
onClick={shiftBy(2 * hour)}
dense={true}
/>
</div>
</div> </div>
<div className={classes.rightShiftButtons}> <div className={classes.controlSelectorBox}>
<ShiftButton <div className={classes.controlEndTimeSelector}>
direction="right" <FormControl
text="5m" component="fieldset"
onClick={shiftBy(5 * minute)} margin="dense"
/> classes={{ root: classes.formControlRoot }}
<ShiftButton
direction="right"
text="15m"
onClick={shiftBy(15 * minute)}
/>
<ShiftButton
direction="right"
text="30m"
onClick={shiftBy(30 * minute)}
/>
<ShiftButton
direction="right"
text="1h"
onClick={shiftBy(1 * hour)}
/>
<ShiftButton
direction="right"
text="2h"
onClick={shiftBy(2 * hour)}
/>
</div>
</div>
<div className={classes.controlSelectorBox}>
<div className={classes.controlEndTimeSelector}>
<FormControl
component="fieldset"
margin="dense"
classes={{ root: classes.formControlRoot }}
>
<FormLabel component="legend">End Time</FormLabel>
<RadioGroup
aria-label="end_time"
name="end_time"
value={state.endTimeOption}
onChange={handleEndTimeOptionChange}
> >
<FormControlLabel <FormLabel component="legend">End Time</FormLabel>
classes={{ <RadioGroup
label: classes.radioButtonLabel, aria-label="end_time"
}} name="end_time"
value="real_time" value={state.endTimeOption}
control={ onChange={handleEndTimeOptionChange}
<Radio >
size="small" <FormControlLabel
classes={{ root: classes.radioButtonRoot }} classes={{
/> label: classes.radioButtonLabel,
} }}
label="Real Time" value="real_time"
/> control={
<FormControlLabel <Radio
classes={{ size="small"
label: classes.radioButtonLabel, classes={{ root: classes.radioButtonRoot }}
}} />
value="freeze_at_now" }
control={ label="Real Time"
<Radio />
size="small" <FormControlLabel
classes={{ root: classes.radioButtonRoot }} classes={{
/> label: classes.radioButtonLabel,
} }}
label="Freeze at now" value="freeze_at_now"
/> control={
<FormControlLabel <Radio
classes={{ size="small"
label: classes.radioButtonLabel, classes={{ root: classes.radioButtonRoot }}
}} />
value="custom" }
control={ label="Freeze at now"
<Radio />
size="small" <FormControlLabel
classes={{ root: classes.radioButtonRoot }} classes={{
/> label: classes.radioButtonLabel,
} }}
label="Custom End Time" value="custom"
/> control={
</RadioGroup> <Radio
<div> size="small"
<TextField classes={{ root: classes.radioButtonRoot }}
id="custom-endtime" />
label="yyyy-mm-dd hh:mm:ssz" }
variant="outlined" label="Custom End Time"
size="small" />
onChange={handleCustomEndTimeChange} </RadioGroup>
value={state.customEndTime} <div>
onKeyDown={handleCustomEndTimeKeyDown} <TextField
error={state.customEndTimeError !== ""} id="custom-endtime"
helperText={state.customEndTimeError} label="yyyy-mm-dd hh:mm:ssz"
/> variant="outlined"
</div> size="small"
</FormControl> onChange={handleCustomEndTimeChange}
</div> value={state.customEndTime}
<div className={classes.controlDurationSelector}> onKeyDown={handleCustomEndTimeKeyDown}
<FormControl error={state.customEndTimeError !== ""}
component="fieldset" helperText={state.customEndTimeError}
margin="dense" />
classes={{ root: classes.formControlRoot }} </div>
> </FormControl>
<FormLabel component="legend">Duration</FormLabel> </div>
<RadioGroup <div className={classes.controlDurationSelector}>
aria-label="duration" <FormControl
name="duration" component="fieldset"
value={state.durationOption} margin="dense"
onChange={handleDurationOptionChange} classes={{ root: classes.formControlRoot }}
> >
<FormControlLabel <FormLabel component="legend">Duration</FormLabel>
classes={{ <RadioGroup
label: classes.radioButtonLabel, aria-label="duration"
}} name="duration"
value="1h" value={state.durationOption}
control={ onChange={handleDurationOptionChange}
<Radio >
size="small" <FormControlLabel
classes={{ root: classes.radioButtonRoot }} classes={{
/> label: classes.radioButtonLabel,
} }}
label="1h" value="1h"
/> control={
<FormControlLabel <Radio
classes={{ size="small"
label: classes.radioButtonLabel, classes={{ root: classes.radioButtonRoot }}
}} />
value="6h" }
control={ label="1h"
<Radio />
size="small" <FormControlLabel
classes={{ root: classes.radioButtonRoot }} classes={{
/> label: classes.radioButtonLabel,
} }}
label="6h" value="6h"
/> control={
<FormControlLabel <Radio
classes={{ size="small"
label: classes.radioButtonLabel, classes={{ root: classes.radioButtonRoot }}
}} />
value="1d" }
control={ label="6h"
<Radio />
size="small" <FormControlLabel
classes={{ root: classes.radioButtonRoot }} classes={{
/> label: classes.radioButtonLabel,
} }}
label="1 day" value="1d"
/> control={
<FormControlLabel <Radio
classes={{ size="small"
label: classes.radioButtonLabel, classes={{ root: classes.radioButtonRoot }}
}} />
value="8d" }
control={ label="1 day"
<Radio />
size="small" <FormControlLabel
classes={{ root: classes.radioButtonRoot }} classes={{
/> label: classes.radioButtonLabel,
} }}
label="8 days" value="8d"
/> control={
<FormControlLabel <Radio
classes={{ size="small"
label: classes.radioButtonLabel, classes={{ root: classes.radioButtonRoot }}
}} />
value="30d" }
control={ label="8 days"
<Radio />
size="small" <FormControlLabel
classes={{ root: classes.radioButtonRoot }} classes={{
/> label: classes.radioButtonLabel,
} }}
label="30 days" value="30d"
/> control={
<FormControlLabel <Radio
classes={{ size="small"
label: classes.radioButtonLabel, classes={{ root: classes.radioButtonRoot }}
}} />
value="custom" }
control={ label="30 days"
<Radio />
size="small" <FormControlLabel
classes={{ root: classes.radioButtonRoot }} classes={{
/> label: classes.radioButtonLabel,
} }}
label="Custom Duration" value="custom"
/> control={
</RadioGroup> <Radio
<div> size="small"
<TextField classes={{ root: classes.radioButtonRoot }}
id="custom-duration" />
label="duration" }
variant="outlined" label="Custom Duration"
size="small" />
onChange={handleCustomDurationChange} </RadioGroup>
value={state.customDuration} <div>
onKeyDown={handleCustomDurationKeyDown} <TextField
error={state.customDurationError !== ""} id="custom-duration"
helperText={state.customDurationError} label="duration"
/> variant="outlined"
</div> size="small"
</FormControl> onChange={handleCustomDurationChange}
value={state.customDuration}
onKeyDown={handleCustomDurationKeyDown}
error={state.customDurationError !== ""}
helperText={state.customDurationError}
/>
</div>
</FormControl>
</div>
</div> </div>
</div> </Popover>
</Popover> </div>
<div className={classes.shiftButtons}>
<ButtonGroup
classes={{ root: classes.buttonGroupRoot }}
size="small"
aria-label="shift buttons"
>
<ShiftButton
direction="left"
text={
state.durationOption === "custom" ? "1h" : state.durationOption
}
onClick={
state.durationOption === "custom"
? shiftBy(-1 * hour)
: shiftBy(-props.durationSec)
}
/>
<ShiftButton
direction="right"
text={
state.durationOption === "custom" ? "1h" : state.durationOption
}
onClick={
state.durationOption === "custom"
? shiftBy(1 * hour)
: shiftBy(props.durationSec)
}
/>
</ButtonGroup>
</div>
</div> </div>
); );
} }
@@ -605,10 +654,11 @@ function formatTime(unixtime: number): string {
return dayjs.unix(unixtime).format("ddd, DD MMM YYYY HH:mm:ss ") + tz; return dayjs.unix(unixtime).format("ddd, DD MMM YYYY HH:mm:ss ") + tz;
} }
interface ShiftButtonProps { interface ShiftButtonProps extends ButtonProps {
text: string; text: string;
onClick: () => void; onClick: () => void;
direction: "left" | "right"; direction: "left" | "right";
dense?: boolean;
} }
const useShiftButtonStyles = makeStyles((theme) => ({ const useShiftButtonStyles = makeStyles((theme) => ({
@@ -616,9 +666,9 @@ const useShiftButtonStyles = makeStyles((theme) => ({
label: { fontSize: 12, textTransform: "none" }, label: { fontSize: 12, textTransform: "none" },
iconRoot: { iconRoot: {
marginRight: (props: ShiftButtonProps) => marginRight: (props: ShiftButtonProps) =>
props.direction === "left" ? -8 : 0, props.direction === "left" && props.dense ? -8 : 0,
marginLeft: (props: ShiftButtonProps) => marginLeft: (props: ShiftButtonProps) =>
props.direction === "right" ? -8 : 0, props.direction === "right" && props.dense ? -8 : 0,
color: theme.palette.grey[700], color: theme.palette.grey[700],
}, },
})); }));
@@ -627,12 +677,12 @@ function ShiftButton(props: ShiftButtonProps) {
const classes = useShiftButtonStyles(props); const classes = useShiftButtonStyles(props);
return ( return (
<Button <Button
{...props}
classes={{ classes={{
root: classes.root, root: classes.root,
label: classes.label, label: classes.label,
}} }}
size="small" size="small"
onClick={props.onClick}
> >
{props.direction === "left" && ( {props.direction === "left" && (
<ArrowLeftIcon classes={{ root: classes.iconRoot }} /> <ArrowLeftIcon classes={{ root: classes.iconRoot }} />
@@ -645,4 +695,8 @@ function ShiftButton(props: ShiftButtonProps) {
); );
} }
ShiftButton.defaultProps = {
dense: false,
};
export default connect(mapStateToProps)(MetricsFetchControls); export default connect(mapStateToProps)(MetricsFetchControls);