diff --git a/app/vmui/packages/vmui/src/components/Configurators/GlobalSettings/TenantsConfiguration/TenantsFields.tsx b/app/vmui/packages/vmui/src/components/Configurators/GlobalSettings/TenantsConfiguration/TenantsFields.tsx new file mode 100644 index 000000000..8b1d2b1bf --- /dev/null +++ b/app/vmui/packages/vmui/src/components/Configurators/GlobalSettings/TenantsConfiguration/TenantsFields.tsx @@ -0,0 +1,150 @@ +import React, { FC, useRef } from "preact/compat"; +import { useTimeDispatch } from "../../../../state/time/TimeStateContext"; +import { ArrowDownIcon, QuestionIcon, StorageIcon } from "../../../Main/Icons"; +import Button from "../../../Main/Button/Button"; +import "./style.scss"; +import "../../TimeRangeSettings/ExecutionControls/style.scss"; +import classNames from "classnames"; +import Popper from "../../../Main/Popper/Popper"; +import { getAppModeEnable } from "../../../../utils/app-mode"; +import Tooltip from "../../../Main/Tooltip/Tooltip"; +import useDeviceDetect from "../../../../hooks/useDeviceDetect"; +import TextField from "../../../Main/TextField/TextField"; +import useBoolean from "../../../../hooks/useBoolean"; +import useStateSearchParams from "../../../../hooks/useStateSearchParams"; +import { useSearchParams } from "react-router-dom"; +import { useEffect } from "react"; + +const TenantsFields: FC = () => { + const appModeEnable = getAppModeEnable(); + const { isMobile } = useDeviceDetect(); + const timeDispatch = useTimeDispatch(); + + const [searchParams, setSearchParams] = useSearchParams(); + const [accountID, setAccountID] = useStateSearchParams("0", "accountID"); + const [projectID, setProjectID] = useStateSearchParams("0", "projectID"); + const formattedTenant = `${accountID}:${projectID}`; + + const buttonRef = useRef(null); + + const { + value: openPopup, + toggle: toggleOpenPopup, + setFalse: handleClosePopup, + } = useBoolean(false); + + const applyChanges = () => { + searchParams.set("accountID", accountID); + searchParams.set("projectID", projectID); + setSearchParams(searchParams); + handleClosePopup(); + timeDispatch({ type: "RUN_QUERY" }); + }; + + const handleReset = () => { + setAccountID(searchParams.get("accountID") || "0"); + setProjectID(searchParams.get("projectID") || "0"); + }; + + useEffect(() => { + if (openPopup) return; + handleReset(); + }, [openPopup]); + + return ( +
+ +
+ {isMobile ? ( +
+ +
+ Tenant ID + {formattedTenant} +
+ +
+ ) : ( + + )} +
+
+ +
+ + +
+ + + +
+
+
+
+ ); +}; + +export default TenantsFields; diff --git a/app/vmui/packages/vmui/src/components/Configurators/GlobalSettings/TenantsConfiguration/style.scss b/app/vmui/packages/vmui/src/components/Configurators/GlobalSettings/TenantsConfiguration/style.scss index 30d6cb60e..1a9f0d008 100644 --- a/app/vmui/packages/vmui/src/components/Configurators/GlobalSettings/TenantsConfiguration/style.scss +++ b/app/vmui/packages/vmui/src/components/Configurators/GlobalSettings/TenantsConfiguration/style.scss @@ -17,11 +17,23 @@ padding: 0 $padding-global $padding-small; } + &_inline { + display: grid; + gap: calc($padding-small/2); + padding: $padding-global; + } + &__search { position: sticky; top: 0; padding: $padding-small $padding-global; background-color: $color-background-block; } + + &__buttons { + display: flex; + justify-content: space-between; + gap: $padding-small; + } } } diff --git a/app/vmui/packages/vmui/src/layouts/LogsLayout/ControlsLogsLayout.tsx b/app/vmui/packages/vmui/src/layouts/LogsLayout/ControlsLogsLayout.tsx index 75ebea04e..6a35f7ed7 100644 --- a/app/vmui/packages/vmui/src/layouts/LogsLayout/ControlsLogsLayout.tsx +++ b/app/vmui/packages/vmui/src/layouts/LogsLayout/ControlsLogsLayout.tsx @@ -3,6 +3,7 @@ import classNames from "classnames"; import GlobalSettings from "../../components/Configurators/GlobalSettings/GlobalSettings"; import { ControlsProps } from "../Header/HeaderControls/HeaderControls"; import { TimeSelector } from "../../components/Configurators/TimeRangeSettings/TimeSelector/TimeSelector"; +import TenantsFields from "../../components/Configurators/GlobalSettings/TenantsConfiguration/TenantsFields"; const ControlsLogsLayout: FC = ({ isMobile }) => { @@ -13,6 +14,7 @@ const ControlsLogsLayout: FC = ({ isMobile }) => { "vm-header-controls_mobile": isMobile, })} > + diff --git a/app/vmui/packages/vmui/src/pages/ExploreLogs/hooks/useFetchLogHits.ts b/app/vmui/packages/vmui/src/pages/ExploreLogs/hooks/useFetchLogHits.ts index 658ff3bc3..0ef23d544 100644 --- a/app/vmui/packages/vmui/src/pages/ExploreLogs/hooks/useFetchLogHits.ts +++ b/app/vmui/packages/vmui/src/pages/ExploreLogs/hooks/useFetchLogHits.ts @@ -4,8 +4,11 @@ import { ErrorTypes, TimeParams } from "../../../types"; import { LogHits } from "../../../api/types"; import dayjs from "dayjs"; import { LOGS_BARS_VIEW } from "../../../constants/logs"; +import { useSearchParams } from "react-router-dom"; export const useFetchLogHits = (server: string, query: string) => { + const [searchParams] = useSearchParams(); + const [logHits, setLogHits] = useState([]); const [isLoading, setIsLoading] = useState<{[key: number]: boolean;}>([]); const [error, setError] = useState(); @@ -22,6 +25,10 @@ export const useFetchLogHits = (server: string, query: string) => { return { signal, method: "POST", + headers: { + AccountID: searchParams.get("accountID") || "0", + ProjectID: searchParams.get("projectID") || "0", + }, body: new URLSearchParams({ query: query.trim(), step: `${step}ms`, @@ -68,7 +75,7 @@ export const useFetchLogHits = (server: string, query: string) => { } } setIsLoading(prev => ({ ...prev, [id]: false })); - }, [url, query]); + }, [url, query, searchParams]); return { logHits, diff --git a/app/vmui/packages/vmui/src/pages/ExploreLogs/hooks/useFetchLogs.ts b/app/vmui/packages/vmui/src/pages/ExploreLogs/hooks/useFetchLogs.ts index 2cc9ae47b..e789f8e6a 100644 --- a/app/vmui/packages/vmui/src/pages/ExploreLogs/hooks/useFetchLogs.ts +++ b/app/vmui/packages/vmui/src/pages/ExploreLogs/hooks/useFetchLogs.ts @@ -3,8 +3,11 @@ import { getLogsUrl } from "../../../api/logs"; import { ErrorTypes, TimeParams } from "../../../types"; import { Logs } from "../../../api/types"; import dayjs from "dayjs"; +import { useSearchParams } from "react-router-dom"; export const useFetchLogs = (server: string, query: string, limit: number) => { + const [searchParams] = useSearchParams(); + const [logs, setLogs] = useState([]); const [isLoading, setIsLoading] = useState<{[key: number]: boolean;}>([]); const [error, setError] = useState(); @@ -16,7 +19,9 @@ export const useFetchLogs = (server: string, query: string, limit: number) => { signal, method: "POST", headers: { - "Accept": "application/stream+json", + Accept: "application/stream+json", + AccountID: searchParams.get("accountID") || "0", + ProjectID: searchParams.get("projectID") || "0", }, body: new URLSearchParams({ query: query.trim(), @@ -69,7 +74,7 @@ export const useFetchLogs = (server: string, query: string, limit: number) => { } return false; } - }, [url, query, limit]); + }, [url, query, limit, searchParams]); return { logs, diff --git a/docs/VictoriaLogs/CHANGELOG.md b/docs/VictoriaLogs/CHANGELOG.md index 8bad44a5f..c3540eac4 100644 --- a/docs/VictoriaLogs/CHANGELOG.md +++ b/docs/VictoriaLogs/CHANGELOG.md @@ -16,6 +16,8 @@ according to [these docs](https://docs.victoriametrics.com/victorialogs/quicksta ## tip +* FEATURE: [web UI](https://docs.victoriametrics.com/victorialogs/querying/#web-ui): add fields for setting AccountID and ProjectID. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/6631). + ## [v0.28.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v0.28.0-victorialogs) Released at 2024-07-10