From 0ff17c3ec49f135ceda37f067dfdd0122d987b6e Mon Sep 17 00:00:00 2001 From: Yury Molodov Date: Tue, 15 Oct 2024 14:52:00 +0200 Subject: [PATCH] vmui: add retention and downsampling filters debug pages (#7238) ### Describe Your Changes - add VMUI pages for filters debug - add `config.json` file to the root of the application. The file structure is as follows: ``` { "license": { "type": "enterprise" or "opensource" } } ``` - refactor navigation configuration files. This refactor enables more flexible customization of menu elements. UI:
Renention filters debug Empty page: ![1723474670](https://github.com/user-attachments/assets/3824bf64-dd22-410a-beb5-9599b8769acd) Results: ![1723474597](https://github.com/user-attachments/assets/1bc074ba-b6a7-4127-8638-65cb32e04db8) Example config: ![1723541836](https://github.com/user-attachments/assets/ccdb7f75-4e77-42c4-98be-4bfa7809a3b0)
Downsampling filters debug Empty page: ![1723474663](https://github.com/user-attachments/assets/7bbd07bd-adce-440f-ba43-f4218e237280) Results: ![1723474589](https://github.com/user-attachments/assets/b793ae08-b685-427d-81f1-1c7c532a244a) Example config: ![1723541828](https://github.com/user-attachments/assets/d2ee4e37-8945-4c0f-a4ca-cff5fe3cfcd2)
### Checklist The following checks are **mandatory**: - [ ] My change adheres [VictoriaMetrics contributing guidelines](https://docs.victoriametrics.com/contributing/). --- app/vmui/packages/vmui/public/config.json | 5 + app/vmui/packages/vmui/src/App.tsx | 10 ++ .../src/api/downsampling-filters-debug.ts | 7 + .../vmui/src/api/retention-filters-debug.ts | 7 + .../packages/vmui/src/constants/navigation.ts | 81 ----------- .../vmui/src/hooks/useFetchAppConfig.ts | 34 +++++ .../layouts/Header/HeaderNav/HeaderNav.tsx | 41 +----- .../src/layouts/Header/HeaderNav/NavItem.tsx | 2 +- .../layouts/Header/HeaderNav/NavSubItem.tsx | 2 +- .../src/layouts/MainLayout/MainLayout.tsx | 2 + .../hooks/useDebugDownsamplingFilters.ts | 53 +++++++ .../src/pages/DownsamplingFilters/index.tsx | 137 ++++++++++++++++++ .../src/pages/DownsamplingFilters/style.scss | 46 ++++++ .../hooks/useDebugRetentionFilters.ts | 53 +++++++ .../vmui/src/pages/RetentionFilters/index.tsx | 137 ++++++++++++++++++ .../src/pages/RetentionFilters/style.scss | 46 ++++++ app/vmui/packages/vmui/src/router/index.ts | 10 ++ .../packages/vmui/src/router/navigation.ts | 92 ++++++++++++ .../vmui/src/router/useNavigationMenu.ts | 43 ++++++ app/vmui/packages/vmui/src/router/utils.ts | 30 ++++ .../packages/vmui/src/state/common/reducer.ts | 10 +- app/vmui/packages/vmui/src/types/index.ts | 6 + 22 files changed, 733 insertions(+), 121 deletions(-) create mode 100644 app/vmui/packages/vmui/public/config.json create mode 100644 app/vmui/packages/vmui/src/api/downsampling-filters-debug.ts create mode 100644 app/vmui/packages/vmui/src/api/retention-filters-debug.ts delete mode 100644 app/vmui/packages/vmui/src/constants/navigation.ts create mode 100644 app/vmui/packages/vmui/src/hooks/useFetchAppConfig.ts create mode 100644 app/vmui/packages/vmui/src/pages/DownsamplingFilters/hooks/useDebugDownsamplingFilters.ts create mode 100644 app/vmui/packages/vmui/src/pages/DownsamplingFilters/index.tsx create mode 100644 app/vmui/packages/vmui/src/pages/DownsamplingFilters/style.scss create mode 100644 app/vmui/packages/vmui/src/pages/RetentionFilters/hooks/useDebugRetentionFilters.ts create mode 100644 app/vmui/packages/vmui/src/pages/RetentionFilters/index.tsx create mode 100644 app/vmui/packages/vmui/src/pages/RetentionFilters/style.scss create mode 100644 app/vmui/packages/vmui/src/router/navigation.ts create mode 100644 app/vmui/packages/vmui/src/router/useNavigationMenu.ts create mode 100644 app/vmui/packages/vmui/src/router/utils.ts diff --git a/app/vmui/packages/vmui/public/config.json b/app/vmui/packages/vmui/public/config.json new file mode 100644 index 000000000..4bb6a1501 --- /dev/null +++ b/app/vmui/packages/vmui/public/config.json @@ -0,0 +1,5 @@ +{ + "license": { + "type": "opensource" + } +} diff --git a/app/vmui/packages/vmui/src/App.tsx b/app/vmui/packages/vmui/src/App.tsx index f2807d7bf..1ffafe55f 100644 --- a/app/vmui/packages/vmui/src/App.tsx +++ b/app/vmui/packages/vmui/src/App.tsx @@ -15,6 +15,8 @@ import WithTemplate from "./pages/WithTemplate"; import Relabel from "./pages/Relabel"; import ActiveQueries from "./pages/ActiveQueries"; import QueryAnalyzer from "./pages/QueryAnalyzer"; +import DownsamplingFilters from "./pages/DownsamplingFilters"; +import RetentionFilters from "./pages/RetentionFilters"; const App: FC = () => { const [loadedTheme, setLoadedTheme] = useState(false); @@ -74,6 +76,14 @@ const App: FC = () => { path={router.icons} element={} /> + } + /> + } + /> )} diff --git a/app/vmui/packages/vmui/src/api/downsampling-filters-debug.ts b/app/vmui/packages/vmui/src/api/downsampling-filters-debug.ts new file mode 100644 index 000000000..4e7147729 --- /dev/null +++ b/app/vmui/packages/vmui/src/api/downsampling-filters-debug.ts @@ -0,0 +1,7 @@ +export const getDownsamplingFiltersDebug = (server: string, flags: string, metrics: string): string => { + const params = [ + `flags=${encodeURIComponent(flags)}`, + `metrics=${encodeURIComponent(metrics)}` + ]; + return `${server}/downsampling-filters-debug?${params.join("&")}`; +}; diff --git a/app/vmui/packages/vmui/src/api/retention-filters-debug.ts b/app/vmui/packages/vmui/src/api/retention-filters-debug.ts new file mode 100644 index 000000000..2bef0bedd --- /dev/null +++ b/app/vmui/packages/vmui/src/api/retention-filters-debug.ts @@ -0,0 +1,7 @@ +export const getRetentionFiltersDebug = (server: string, flags: string, metrics: string): string => { + const params = [ + `flags=${encodeURIComponent(flags)}`, + `metrics=${encodeURIComponent(metrics)}` + ]; + return `${server}/retention-filters-debug?${params.join("&")}`; +}; diff --git a/app/vmui/packages/vmui/src/constants/navigation.ts b/app/vmui/packages/vmui/src/constants/navigation.ts deleted file mode 100644 index 0df6c64d7..000000000 --- a/app/vmui/packages/vmui/src/constants/navigation.ts +++ /dev/null @@ -1,81 +0,0 @@ -import router, { routerOptions } from "../router"; - -export enum NavigationItemType { - internalLink, - externalLink, -} - -export interface NavigationItem { - label?: string, - value?: string, - hide?: boolean - submenu?: NavigationItem[], - type?: NavigationItemType, -} - -const explore = { - label: "Explore", - submenu: [ - { - label: routerOptions[router.metrics].title, - value: router.metrics, - }, - { - label: routerOptions[router.cardinality].title, - value: router.cardinality, - }, - { - label: routerOptions[router.topQueries].title, - value: router.topQueries, - }, - { - label: routerOptions[router.activeQueries].title, - value: router.activeQueries, - }, - ] -}; - -const tools = { - label: "Tools", - submenu: [ - { - label: routerOptions[router.trace].title, - value: router.trace, - }, - { - label: routerOptions[router.queryAnalyzer].title, - value: router.queryAnalyzer, - }, - { - label: routerOptions[router.withTemplate].title, - value: router.withTemplate, - }, - { - label: routerOptions[router.relabel].title, - value: router.relabel, - }, - ] -}; - -export const logsNavigation: NavigationItem[] = [ - { - label: routerOptions[router.logs].title, - value: router.home, - }, -]; - -export const anomalyNavigation: NavigationItem[] = [ - { - label: routerOptions[router.anomaly].title, - value: router.home, - } -]; - -export const defaultNavigation: NavigationItem[] = [ - { - label: routerOptions[router.home].title, - value: router.home, - }, - explore, - tools, -]; diff --git a/app/vmui/packages/vmui/src/hooks/useFetchAppConfig.ts b/app/vmui/packages/vmui/src/hooks/useFetchAppConfig.ts new file mode 100644 index 000000000..ac0bbffdd --- /dev/null +++ b/app/vmui/packages/vmui/src/hooks/useFetchAppConfig.ts @@ -0,0 +1,34 @@ +import { useAppDispatch } from "../state/common/StateContext"; +import { useEffect, useState } from "preact/compat"; +import { ErrorTypes } from "../types"; + +const useFetchFlags = () => { + const dispatch = useAppDispatch(); + + const [isLoading, setIsLoading] = useState(false); + const [error, setError] = useState(""); + + useEffect(() => { + const fetchAppConfig = async () => { + if (process.env.REACT_APP_TYPE) return; + setError(""); + setIsLoading(true); + + try { + const data = await fetch("./config.json"); + const config = await data.json(); + dispatch({ type: "SET_APP_CONFIG", payload: config || {} }); + } catch (e) { + setIsLoading(false); + if (e instanceof Error) setError(`${e.name}: ${e.message}`); + } + }; + + fetchAppConfig(); + }, []); + + return { isLoading, error }; +}; + +export default useFetchFlags; + diff --git a/app/vmui/packages/vmui/src/layouts/Header/HeaderNav/HeaderNav.tsx b/app/vmui/packages/vmui/src/layouts/Header/HeaderNav/HeaderNav.tsx index 88c8bc19d..4f009cf36 100644 --- a/app/vmui/packages/vmui/src/layouts/Header/HeaderNav/HeaderNav.tsx +++ b/app/vmui/packages/vmui/src/layouts/Header/HeaderNav/HeaderNav.tsx @@ -1,16 +1,12 @@ -import React, { FC, useMemo, useState } from "preact/compat"; -import router, { routerOptions } from "../../../router"; -import { getAppModeEnable } from "../../../utils/app-mode"; +import React, { FC, useState } from "preact/compat"; import { useLocation } from "react-router-dom"; -import { useDashboardsState } from "../../../state/dashboards/DashboardsStateContext"; import { useEffect } from "react"; import "./style.scss"; import NavItem from "./NavItem"; import NavSubItem from "./NavSubItem"; import classNames from "classnames"; -import { anomalyNavigation, defaultNavigation, logsNavigation, NavigationItemType } from "../../../constants/navigation"; -import { AppType } from "../../../types/appType"; -import { useAppState } from "../../../state/common/StateContext"; +import useNavigationMenu from "../../../router/useNavigationMenu"; +import { NavigationItemType } from "../../../router/navigation"; interface HeaderNavProps { color: string @@ -19,43 +15,14 @@ interface HeaderNavProps { } const HeaderNav: FC = ({ color, background, direction }) => { - const appModeEnable = getAppModeEnable(); - const { dashboardsSettings } = useDashboardsState(); const { pathname } = useLocation(); - const { serverUrl, flags } = useAppState(); - const [activeMenu, setActiveMenu] = useState(pathname); - - const menu = useMemo(() => { - switch (process.env.REACT_APP_TYPE) { - case AppType.logs: - return logsNavigation; - case AppType.anomaly: - return anomalyNavigation; - default: - return ([ - ...defaultNavigation, - { - label: routerOptions[router.dashboards].title, - value: router.dashboards, - hide: appModeEnable || !dashboardsSettings.length, - }, - { - // see more https://docs.victoriametrics.com/cluster-victoriametrics/?highlight=vmalertproxyurl#vmalert - label: "Alerts", - value: `${serverUrl}/vmalert`, - type: NavigationItemType.externalLink, - hide: !Object.keys(flags).includes("vmalert.proxyURL"), - }, - ].filter(r => !r.hide)); - } - }, [appModeEnable, dashboardsSettings]); + const menu = useNavigationMenu(); useEffect(() => { setActiveMenu(pathname); }, [pathname]); - return (