mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
vmui: Improve DownloadConfig button interaction with VMAnomaly (#6397)
Co-authored-by: Dzmitry Lazerka <dlazerka@gmail.com>
This commit is contained in:
parent
2e3c039113
commit
362ee240cd
7 changed files with 34 additions and 8 deletions
|
@ -71,6 +71,7 @@
|
|||
"eslint": "^8.44.0",
|
||||
"eslint-config-react-app": "^7.0.1",
|
||||
"eslint-plugin-react": "^7.29.4",
|
||||
"http-proxy-middleware": "^3.0.0",
|
||||
"react-app-rewired": "^2.2.1",
|
||||
"webpack": "^5.88.1"
|
||||
},
|
||||
|
|
|
@ -9,6 +9,9 @@ import useDeviceDetect from "../../hooks/useDeviceDetect";
|
|||
import { useAppState } from "../../state/common/StateContext";
|
||||
import classNames from "classnames";
|
||||
import "./style.scss";
|
||||
import { useQueryState } from "../../state/query/QueryStateContext";
|
||||
import { useTimeState } from "../../state/time/TimeStateContext";
|
||||
import { getStepFromDuration } from "../../utils/time";
|
||||
|
||||
const AnomalyConfig: FC = () => {
|
||||
const { serverUrl } = useAppState();
|
||||
|
@ -20,6 +23,8 @@ const AnomalyConfig: FC = () => {
|
|||
setFalse: setCloseModal,
|
||||
} = useBoolean(false);
|
||||
|
||||
const { query } = useQueryState();
|
||||
const { period } = useTimeState();
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [textConfig, setTextConfig] = useState<string>("");
|
||||
const [downloadUrl, setDownloadUrl] = useState<string>("");
|
||||
|
@ -28,15 +33,22 @@ const AnomalyConfig: FC = () => {
|
|||
const fetchConfig = async () => {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const url = `${serverUrl}/api/vmanomaly/config.yaml`;
|
||||
const queryParam = encodeURIComponent(query[0] || "");
|
||||
const stepParam = encodeURIComponent(period.step || getStepFromDuration(period.end - period.start, false));
|
||||
|
||||
const url = `${serverUrl}/api/vmanomaly/config.yaml?query=${queryParam}&step=${stepParam}`;
|
||||
const response = await fetch(url);
|
||||
const contentType = response.headers.get("Content-Type");
|
||||
if (!response.ok) {
|
||||
setError(` ${response.status} ${response.statusText}`);
|
||||
} else {
|
||||
const bodyText = await response.text();
|
||||
setError(` ${response.status} ${response.statusText}: ${bodyText}`);
|
||||
} else if (contentType == "application/yaml") {
|
||||
const blob = await response.blob();
|
||||
const yamlAsString = await blob.text();
|
||||
setTextConfig(yamlAsString);
|
||||
setDownloadUrl(URL.createObjectURL(blob));
|
||||
} else {
|
||||
setError("Response Content-Type is not YAML, does `Server URL` point to VMAnomaly server?");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
|
|
|
@ -88,9 +88,11 @@ const Modal: FC<ModalProps> = ({
|
|||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
{/* tabIndex to fix Ctrl-A */}
|
||||
<div
|
||||
className="vm-modal-content-body"
|
||||
onMouseDown={handleMouseDown}
|
||||
tabIndex={0}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
|
|
|
@ -12,7 +12,7 @@ import { useTimeState } from "../state/time/TimeStateContext";
|
|||
import { useCustomPanelState } from "../state/customPanel/CustomPanelStateContext";
|
||||
import { isHistogramData } from "../utils/metric";
|
||||
import { useGraphState } from "../state/graph/GraphStateContext";
|
||||
import { getSecondsFromDuration, getStepFromDuration } from "../utils/time";
|
||||
import { getStepFromDuration } from "../utils/time";
|
||||
import { AppType } from "../types/appType";
|
||||
|
||||
interface FetchQueryParams {
|
||||
|
@ -183,7 +183,7 @@ export const useFetchQuery = ({
|
|||
setQueryErrors(expr.map(() => ErrorTypes.validQuery));
|
||||
} else if (isValidHttpUrl(serverUrl)) {
|
||||
const updatedPeriod = { ...period };
|
||||
updatedPeriod.step = isAnomalyUI ? `${getSecondsFromDuration(customStep)*1000}ms` : customStep;
|
||||
updatedPeriod.step = customStep;
|
||||
return expr.map(q => displayChart
|
||||
? getQueryRangeUrl(serverUrl, q, updatedPeriod, nocache, isTracingEnabled)
|
||||
: getQueryUrl(serverUrl, q, updatedPeriod, nocache, isTracingEnabled));
|
||||
|
|
|
@ -87,7 +87,7 @@ const ExploreAnomaly: FC = () => {
|
|||
setHideError={setHideError}
|
||||
stats={queryStats}
|
||||
onRunQuery={handleRunQuery}
|
||||
hideButtons={{ addQuery: true, prettify: true, autocomplete: true, traceQuery: true, anomalyConfig: true }}
|
||||
hideButtons={{ addQuery: true, prettify: false, autocomplete: false, traceQuery: true, anomalyConfig: true }}
|
||||
/>
|
||||
{isLoading && <Spinner/>}
|
||||
{(!hideError && error) && <Alert variant="error">{error}</Alert>}
|
||||
|
|
11
app/vmui/packages/vmui/src/setupProxy.js
Normal file
11
app/vmui/packages/vmui/src/setupProxy.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
const { createProxyMiddleware } = require('http-proxy-middleware');
|
||||
|
||||
module.exports = function (app) {
|
||||
app.use(
|
||||
"/api",
|
||||
createProxyMiddleware({
|
||||
target: "http://localhost:8490/api",
|
||||
changeOrigin: true,
|
||||
})
|
||||
);
|
||||
};
|
|
@ -34,7 +34,7 @@ export const humanizeSeconds = (num: number): string => {
|
|||
return getDurationFromMilliseconds(dayjs.duration(num, "seconds").asMilliseconds());
|
||||
};
|
||||
|
||||
export const roundStep = (step: number) => {
|
||||
export const roundStep = (step: number): string => {
|
||||
let result = roundToMilliseconds(step);
|
||||
const integerStep = Math.round(step);
|
||||
|
||||
|
@ -87,7 +87,7 @@ export const getSecondsFromDuration = (dur: string) => {
|
|||
return dayjs.duration(durObject).asSeconds();
|
||||
};
|
||||
|
||||
export const getStepFromDuration = (dur: number, histogram?: boolean) => {
|
||||
export const getStepFromDuration = (dur: number, histogram?: boolean): string => {
|
||||
const size = histogram ? MAX_ITEMS_PER_HISTOGRAM : MAX_ITEMS_PER_CHART;
|
||||
return roundStep(dur / size);
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue