mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2025-01-10 15:14:09 +00:00
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:
parent
9aee303ca1
commit
54e1865d17
6 changed files with 61 additions and 41 deletions
|
@ -30,8 +30,8 @@ const GlobalSettings: FC = () => {
|
|||
const dispatch = useAppDispatch();
|
||||
const [changedServerUrl, setChangedServerUrl] = useState(serverUrl);
|
||||
|
||||
const setServer = () => {
|
||||
dispatch({type: "SET_SERVER", payload: changedServerUrl});
|
||||
const setServer = (url?: string) => {
|
||||
dispatch({type: "SET_SERVER", payload: url || changedServerUrl});
|
||||
handleClose();
|
||||
};
|
||||
|
||||
|
@ -63,12 +63,12 @@ const GlobalSettings: FC = () => {
|
|||
<CloseIcon/>
|
||||
</IconButton>
|
||||
</Box>
|
||||
<ServerConfigurator setServer={setChangedServerUrl}/>
|
||||
<ServerConfigurator setServer={setChangedServerUrl} onEnter={setServer}/>
|
||||
<Box display="grid" gridTemplateColumns="auto auto" gap={1} justifyContent="end" mt={4}>
|
||||
<Button variant="outlined" onClick={handleClose}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button variant="contained" onClick={setServer}>
|
||||
<Button variant="contained" onClick={() => setServer()}>
|
||||
apply
|
||||
</Button>
|
||||
</Box>
|
||||
|
|
|
@ -2,14 +2,15 @@ import React, {FC, useState} from "preact/compat";
|
|||
import TextField from "@mui/material/TextField";
|
||||
import {useAppState} from "../../../../state/common/StateContext";
|
||||
import {ErrorTypes} from "../../../../types";
|
||||
import {ChangeEvent} from "react";
|
||||
import {ChangeEvent, KeyboardEvent} from "react";
|
||||
|
||||
export interface ServerConfiguratorProps {
|
||||
error?: ErrorTypes | string;
|
||||
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 [changedServerUrl, setChangedServerUrl] = useState(serverUrl);
|
||||
|
@ -20,10 +21,24 @@ const ServerConfigurator: FC<ServerConfiguratorProps> = ({error, setServer}) =>
|
|||
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}
|
||||
inputProps={{style: {fontFamily: "Monospace"}}}
|
||||
onChange={onChangeServer}/>;
|
||||
onChange={onChangeServer}
|
||||
onKeyDown={onKeyDown}
|
||||
/>;
|
||||
};
|
||||
|
||||
export default ServerConfigurator;
|
||||
|
|
|
@ -12,6 +12,7 @@ import ListItem from "@mui/material/ListItem";
|
|||
import ListItemText from "@mui/material/ListItemText";
|
||||
import {useLocation} from "react-router-dom";
|
||||
import {getAppModeEnable} from "../../../../utils/app-mode";
|
||||
import Box from "@mui/material/Box";
|
||||
|
||||
interface AutoRefreshOption {
|
||||
seconds: number
|
||||
|
@ -55,12 +56,16 @@ export const ExecutionControls: FC = () => {
|
|||
setAnchorEl(null);
|
||||
};
|
||||
|
||||
const handleUpdate = () => {
|
||||
dispatch({type: "RUN_QUERY"});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const delay = selectedDelay.seconds;
|
||||
let timer: number;
|
||||
if (autoRefresh) {
|
||||
timer = setInterval(() => {
|
||||
dispatch({type: "RUN_QUERY_TO_NOW"});
|
||||
dispatch({type: "RUN_QUERY"});
|
||||
}, delay * 1000) as unknown as number;
|
||||
} else {
|
||||
setSelectedDelay(delayOptions[0]);
|
||||
|
@ -74,22 +79,33 @@ export const ExecutionControls: FC = () => {
|
|||
const open = Boolean(anchorEl);
|
||||
|
||||
return <>
|
||||
<Tooltip title="Auto-refresh control">
|
||||
<Button variant="contained" color="primary"
|
||||
sx={{
|
||||
minWidth: "110px",
|
||||
color: "white",
|
||||
border: appModeEnable ? "none" : "1px solid rgba(0, 0, 0, 0.2)",
|
||||
justifyContent: "space-between",
|
||||
boxShadow: "none",
|
||||
}}
|
||||
startIcon={<AutorenewIcon/>}
|
||||
endIcon={<KeyboardArrowDownIcon sx={{transform: open ? "rotate(180deg)" : "none"}}/>}
|
||||
onClick={(e) => setAnchorEl(e.currentTarget)}
|
||||
>
|
||||
{selectedDelay.title}
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Box sx={{
|
||||
minWidth: "110px",
|
||||
color: "white",
|
||||
border: appModeEnable ? "none" : "1px solid rgba(0, 0, 0, 0.2)",
|
||||
justifyContent: "space-between",
|
||||
boxShadow: "none",
|
||||
borderRadius: "4px",
|
||||
display: "grid",
|
||||
gridTemplateColumns: "auto 1fr"
|
||||
}}>
|
||||
<Tooltip title="Refresh dashboard">
|
||||
<Button variant="contained" color="primary"
|
||||
sx={{color: "white", minWidth: "34px", boxShadow: "none", borderRadius: "3px 0 0 3px", p: "6px 6px"}}
|
||||
startIcon={<AutorenewIcon fontSize={"small"} style={{marginRight: "-8px", marginLeft: "4px"}}/>}
|
||||
onClick={handleUpdate}
|
||||
>
|
||||
</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
|
||||
open={open}
|
||||
anchorEl={anchorEl}
|
||||
|
@ -97,7 +113,7 @@ export const ExecutionControls: FC = () => {
|
|||
modifiers={[{name: "offset", options: {offset: [0, 6]}}]}>
|
||||
<ClickAwayListener onClickAway={() => setAnchorEl(null)}>
|
||||
<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 =>
|
||||
<ListItem key={d.seconds} button onClick={() => handleChange(d)}>
|
||||
<ListItemText primary={d.title}/>
|
||||
|
|
|
@ -73,11 +73,8 @@ export const TimeSelector: FC = () => {
|
|||
|
||||
const open = Boolean(anchorEl);
|
||||
const setTimeAndClosePicker = () => {
|
||||
if (from) {
|
||||
dispatch({type: "SET_FROM", payload: new Date(from)});
|
||||
}
|
||||
if (until) {
|
||||
dispatch({type: "SET_UNTIL", payload: new Date(until)});
|
||||
if (from && until) {
|
||||
dispatch({type: "SET_PERIOD", payload: {from: new Date(from), to: new Date(until)}});
|
||||
}
|
||||
setAnchorEl(null);
|
||||
};
|
||||
|
|
|
@ -6,8 +6,6 @@ import {isValidHttpUrl} from "../utils/url";
|
|||
import {ErrorTypes} from "../types";
|
||||
import debounce from "lodash.debounce";
|
||||
import {DisplayType} from "../components/CustomPanel/Configurator/DisplayTypeSwitch";
|
||||
import usePrevious from "./usePrevious";
|
||||
import {arrayEquals} from "../utils/array";
|
||||
import Trace from "../components/CustomPanel/Trace/Trace";
|
||||
import {MAX_SERIES} from "../config";
|
||||
|
||||
|
@ -94,7 +92,7 @@ export const useFetchQuery = ({predefinedQuery, visible, display, customStep}: F
|
|||
setIsLoading(false);
|
||||
};
|
||||
|
||||
const throttledFetchData = useCallback(debounce(fetchData, 600), []);
|
||||
const throttledFetchData = useCallback(debounce(fetchData, 800), []);
|
||||
|
||||
const fetchUrl = useMemo(() => {
|
||||
const expr = predefinedQuery ?? query;
|
||||
|
@ -116,13 +114,8 @@ export const useFetchQuery = ({predefinedQuery, visible, display, customStep}: F
|
|||
},
|
||||
[serverUrl, period, displayType, customStep]);
|
||||
|
||||
const prevFetchUrl = usePrevious(fetchUrl);
|
||||
const prevDisplayType = usePrevious(displayType);
|
||||
|
||||
useEffect(() => {
|
||||
const equalFetchUrl = fetchUrl && prevFetchUrl && arrayEquals(fetchUrl, prevFetchUrl);
|
||||
const changedDisplayType = displayType !== prevDisplayType;
|
||||
if (!visible || (equalFetchUrl && !changedDisplayType) || !fetchUrl?.length) return;
|
||||
if (!visible || !fetchUrl?.length) return;
|
||||
setIsLoading(true);
|
||||
const expr = predefinedQuery ?? query;
|
||||
throttledFetchData(fetchUrl, fetchQueue, (display || displayType), expr);
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { useEffect, useState } from "react";
|
||||
import {ErrorTypes} from "../types";
|
||||
import {getAppModeParams} from "../utils/app-mode";
|
||||
import {useAppState} from "../state/common/StateContext";
|
||||
import {useMemo} from "preact/compat";
|
||||
import {getTopQueries} from "../api/top-queries";
|
||||
|
|
Loading…
Reference in a new issue