vmui: minor fixes (#3276)

* feat: apply serverURL on down Enter

* fix: change method of set time range

* fix: remove prevent run fetch without changes

* fix: prevent reset timerange when autorefresh
This commit is contained in:
Yury Molodov 2022-10-28 13:47:50 +02:00 committed by GitHub
parent 9aee303ca1
commit 54e1865d17
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 61 additions and 41 deletions

View file

@ -30,8 +30,8 @@ const GlobalSettings: FC = () => {
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const [changedServerUrl, setChangedServerUrl] = useState(serverUrl); const [changedServerUrl, setChangedServerUrl] = useState(serverUrl);
const setServer = () => { const setServer = (url?: string) => {
dispatch({type: "SET_SERVER", payload: changedServerUrl}); dispatch({type: "SET_SERVER", payload: url || changedServerUrl});
handleClose(); handleClose();
}; };
@ -63,12 +63,12 @@ const GlobalSettings: FC = () => {
<CloseIcon/> <CloseIcon/>
</IconButton> </IconButton>
</Box> </Box>
<ServerConfigurator setServer={setChangedServerUrl}/> <ServerConfigurator setServer={setChangedServerUrl} onEnter={setServer}/>
<Box display="grid" gridTemplateColumns="auto auto" gap={1} justifyContent="end" mt={4}> <Box display="grid" gridTemplateColumns="auto auto" gap={1} justifyContent="end" mt={4}>
<Button variant="outlined" onClick={handleClose}> <Button variant="outlined" onClick={handleClose}>
Cancel Cancel
</Button> </Button>
<Button variant="contained" onClick={setServer}> <Button variant="contained" onClick={() => setServer()}>
apply apply
</Button> </Button>
</Box> </Box>

View file

@ -2,14 +2,15 @@ import React, {FC, useState} from "preact/compat";
import TextField from "@mui/material/TextField"; import TextField from "@mui/material/TextField";
import {useAppState} from "../../../../state/common/StateContext"; import {useAppState} from "../../../../state/common/StateContext";
import {ErrorTypes} from "../../../../types"; import {ErrorTypes} from "../../../../types";
import {ChangeEvent} from "react"; import {ChangeEvent, KeyboardEvent} from "react";
export interface ServerConfiguratorProps { export interface ServerConfiguratorProps {
error?: ErrorTypes | string; error?: ErrorTypes | string;
setServer: (url: string) => void setServer: (url: string) => void
onEnter: (url: string) => void
} }
const ServerConfigurator: FC<ServerConfiguratorProps> = ({error, setServer}) => { const ServerConfigurator: FC<ServerConfiguratorProps> = ({error, setServer, onEnter}) => {
const {serverUrl} = useAppState(); const {serverUrl} = useAppState();
const [changedServerUrl, setChangedServerUrl] = useState(serverUrl); const [changedServerUrl, setChangedServerUrl] = useState(serverUrl);
@ -20,10 +21,24 @@ const ServerConfigurator: FC<ServerConfiguratorProps> = ({error, setServer}) =>
setServer(value); setServer(value);
}; };
return <TextField variant="outlined" fullWidth label="Server URL" value={changedServerUrl || ""} const onKeyDown = (e: KeyboardEvent) => {
if (e.key === "Enter") {
e.preventDefault();
onEnter(changedServerUrl);
}
};
return <TextField
autoFocus
fullWidth
variant="outlined"
label="Server URL"
value={changedServerUrl || ""}
error={error === ErrorTypes.validServer || error === ErrorTypes.emptyServer} error={error === ErrorTypes.validServer || error === ErrorTypes.emptyServer}
inputProps={{style: {fontFamily: "Monospace"}}} inputProps={{style: {fontFamily: "Monospace"}}}
onChange={onChangeServer}/>; onChange={onChangeServer}
onKeyDown={onKeyDown}
/>;
}; };
export default ServerConfigurator; export default ServerConfigurator;

View file

@ -12,6 +12,7 @@ import ListItem from "@mui/material/ListItem";
import ListItemText from "@mui/material/ListItemText"; import ListItemText from "@mui/material/ListItemText";
import {useLocation} from "react-router-dom"; import {useLocation} from "react-router-dom";
import {getAppModeEnable} from "../../../../utils/app-mode"; import {getAppModeEnable} from "../../../../utils/app-mode";
import Box from "@mui/material/Box";
interface AutoRefreshOption { interface AutoRefreshOption {
seconds: number seconds: number
@ -55,12 +56,16 @@ export const ExecutionControls: FC = () => {
setAnchorEl(null); setAnchorEl(null);
}; };
const handleUpdate = () => {
dispatch({type: "RUN_QUERY"});
};
useEffect(() => { useEffect(() => {
const delay = selectedDelay.seconds; const delay = selectedDelay.seconds;
let timer: number; let timer: number;
if (autoRefresh) { if (autoRefresh) {
timer = setInterval(() => { timer = setInterval(() => {
dispatch({type: "RUN_QUERY_TO_NOW"}); dispatch({type: "RUN_QUERY"});
}, delay * 1000) as unknown as number; }, delay * 1000) as unknown as number;
} else { } else {
setSelectedDelay(delayOptions[0]); setSelectedDelay(delayOptions[0]);
@ -74,22 +79,33 @@ export const ExecutionControls: FC = () => {
const open = Boolean(anchorEl); const open = Boolean(anchorEl);
return <> return <>
<Tooltip title="Auto-refresh control"> <Box sx={{
<Button variant="contained" color="primary" minWidth: "110px",
sx={{ color: "white",
minWidth: "110px", border: appModeEnable ? "none" : "1px solid rgba(0, 0, 0, 0.2)",
color: "white", justifyContent: "space-between",
border: appModeEnable ? "none" : "1px solid rgba(0, 0, 0, 0.2)", boxShadow: "none",
justifyContent: "space-between", borderRadius: "4px",
boxShadow: "none", display: "grid",
}} gridTemplateColumns: "auto 1fr"
startIcon={<AutorenewIcon/>} }}>
endIcon={<KeyboardArrowDownIcon sx={{transform: open ? "rotate(180deg)" : "none"}}/>} <Tooltip title="Refresh dashboard">
onClick={(e) => setAnchorEl(e.currentTarget)} <Button variant="contained" color="primary"
> sx={{color: "white", minWidth: "34px", boxShadow: "none", borderRadius: "3px 0 0 3px", p: "6px 6px"}}
{selectedDelay.title} startIcon={<AutorenewIcon fontSize={"small"} style={{marginRight: "-8px", marginLeft: "4px"}}/>}
</Button> onClick={handleUpdate}
</Tooltip> >
</Button>
</Tooltip>
<Tooltip title="Auto-refresh control">
<Button variant="contained" color="primary" sx={{boxShadow: "none", borderRadius: "0 3px 3px 0"}} fullWidth
endIcon={<KeyboardArrowDownIcon sx={{transform: open ? "rotate(180deg)" : "none"}}/>}
onClick={(e) => setAnchorEl(e.currentTarget)}
>
{selectedDelay.title}
</Button>
</Tooltip>
</Box>
<Popper <Popper
open={open} open={open}
anchorEl={anchorEl} anchorEl={anchorEl}
@ -97,7 +113,7 @@ export const ExecutionControls: FC = () => {
modifiers={[{name: "offset", options: {offset: [0, 6]}}]}> modifiers={[{name: "offset", options: {offset: [0, 6]}}]}>
<ClickAwayListener onClickAway={() => setAnchorEl(null)}> <ClickAwayListener onClickAway={() => setAnchorEl(null)}>
<Paper elevation={3}> <Paper elevation={3}>
<List style={{minWidth: "110px",maxHeight: "208px", overflow: "auto", padding: "20px 0"}}> <List style={{minWidth: "110px", maxHeight: "208px", overflow: "auto", padding: "20px 0"}}>
{delayOptions.map(d => {delayOptions.map(d =>
<ListItem key={d.seconds} button onClick={() => handleChange(d)}> <ListItem key={d.seconds} button onClick={() => handleChange(d)}>
<ListItemText primary={d.title}/> <ListItemText primary={d.title}/>

View file

@ -73,11 +73,8 @@ export const TimeSelector: FC = () => {
const open = Boolean(anchorEl); const open = Boolean(anchorEl);
const setTimeAndClosePicker = () => { const setTimeAndClosePicker = () => {
if (from) { if (from && until) {
dispatch({type: "SET_FROM", payload: new Date(from)}); dispatch({type: "SET_PERIOD", payload: {from: new Date(from), to: new Date(until)}});
}
if (until) {
dispatch({type: "SET_UNTIL", payload: new Date(until)});
} }
setAnchorEl(null); setAnchorEl(null);
}; };

View file

@ -6,8 +6,6 @@ import {isValidHttpUrl} from "../utils/url";
import {ErrorTypes} from "../types"; import {ErrorTypes} from "../types";
import debounce from "lodash.debounce"; import debounce from "lodash.debounce";
import {DisplayType} from "../components/CustomPanel/Configurator/DisplayTypeSwitch"; import {DisplayType} from "../components/CustomPanel/Configurator/DisplayTypeSwitch";
import usePrevious from "./usePrevious";
import {arrayEquals} from "../utils/array";
import Trace from "../components/CustomPanel/Trace/Trace"; import Trace from "../components/CustomPanel/Trace/Trace";
import {MAX_SERIES} from "../config"; import {MAX_SERIES} from "../config";
@ -94,7 +92,7 @@ export const useFetchQuery = ({predefinedQuery, visible, display, customStep}: F
setIsLoading(false); setIsLoading(false);
}; };
const throttledFetchData = useCallback(debounce(fetchData, 600), []); const throttledFetchData = useCallback(debounce(fetchData, 800), []);
const fetchUrl = useMemo(() => { const fetchUrl = useMemo(() => {
const expr = predefinedQuery ?? query; const expr = predefinedQuery ?? query;
@ -116,13 +114,8 @@ export const useFetchQuery = ({predefinedQuery, visible, display, customStep}: F
}, },
[serverUrl, period, displayType, customStep]); [serverUrl, period, displayType, customStep]);
const prevFetchUrl = usePrevious(fetchUrl);
const prevDisplayType = usePrevious(displayType);
useEffect(() => { useEffect(() => {
const equalFetchUrl = fetchUrl && prevFetchUrl && arrayEquals(fetchUrl, prevFetchUrl); if (!visible || !fetchUrl?.length) return;
const changedDisplayType = displayType !== prevDisplayType;
if (!visible || (equalFetchUrl && !changedDisplayType) || !fetchUrl?.length) return;
setIsLoading(true); setIsLoading(true);
const expr = predefinedQuery ?? query; const expr = predefinedQuery ?? query;
throttledFetchData(fetchUrl, fetchQueue, (display || displayType), expr); throttledFetchData(fetchUrl, fetchQueue, (display || displayType), expr);

View file

@ -1,6 +1,5 @@
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import {ErrorTypes} from "../types"; import {ErrorTypes} from "../types";
import {getAppModeParams} from "../utils/app-mode";
import {useAppState} from "../state/common/StateContext"; import {useAppState} from "../state/common/StateContext";
import {useMemo} from "preact/compat"; import {useMemo} from "preact/compat";
import {getTopQueries} from "../api/top-queries"; import {getTopQueries} from "../api/top-queries";