From 697327a51d23b8201982c02480d2f7ee7c855725 Mon Sep 17 00:00:00 2001 From: Julius Volz Date: Wed, 28 Aug 2024 15:35:32 +0200 Subject: [PATCH] Add filtering to SD page and improve state processing Signed-off-by: Julius Volz --- web/ui/mantine-ui/src/Badge.module.css | 8 ++ .../ServiceDiscoveryPage.tsx | 27 ++++- .../ServiceDiscoveryPoolsList.tsx | 102 +++++++++++------- .../src/pages/targets/ScrapePoolsList.tsx | 34 +++--- 4 files changed, 114 insertions(+), 57 deletions(-) diff --git a/web/ui/mantine-ui/src/Badge.module.css b/web/ui/mantine-ui/src/Badge.module.css index 26ce908fca..afa27cea2e 100644 --- a/web/ui/mantine-ui/src/Badge.module.css +++ b/web/ui/mantine-ui/src/Badge.module.css @@ -41,6 +41,14 @@ ); } +.healthInfo { + background-color: light-dark( + var(--mantine-color-blue-1), + var(--mantine-color-blue-9) + ); + color: light-dark(var(--mantine-color-blue-9), var(--mantine-color-blue-1)); +} + .healthUnknown { background-color: light-dark( var(--mantine-color-gray-2), diff --git a/web/ui/mantine-ui/src/pages/service-discovery/ServiceDiscoveryPage.tsx b/web/ui/mantine-ui/src/pages/service-discovery/ServiceDiscoveryPage.tsx index 2b870fb073..3b277022fe 100644 --- a/web/ui/mantine-ui/src/pages/service-discovery/ServiceDiscoveryPage.tsx +++ b/web/ui/mantine-ui/src/pages/service-discovery/ServiceDiscoveryPage.tsx @@ -14,7 +14,12 @@ import { import { Suspense } from "react"; import { useAppDispatch, useAppSelector } from "../../state/hooks"; -import { StringParam, useQueryParam, withDefault } from "use-query-params"; +import { + ArrayParam, + StringParam, + useQueryParam, + withDefault, +} from "use-query-params"; import ErrorBoundary from "../../components/ErrorBoundary"; import ScrapePoolList from "./ServiceDiscoveryPoolsList"; import { useSuspenseAPIQuery } from "../../api/api"; @@ -23,6 +28,8 @@ import { setCollapsedPools, setShowLimitAlert, } from "../../state/serviceDiscoveryPageSlice"; +import { StateMultiSelect } from "../../components/StateMultiSelect"; +import badgeClasses from "../../Badge.module.css"; export const targetPoolDisplayLimit = 20; @@ -38,9 +45,13 @@ export default function ServiceDiscoveryPage() { const dispatch = useAppDispatch(); - const [scrapePool, setScrapePool] = useQueryParam("scrapePool", StringParam); + const [scrapePool, setScrapePool] = useQueryParam("pool", StringParam); + const [stateFilter, setStateFilter] = useQueryParam( + "state", + withDefault(ArrayParam, []) + ); const [searchFilter, setSearchFilter] = useQueryParam( - "searchFilter", + "search", withDefault(StringParam, "") ); @@ -76,6 +87,15 @@ export default function ServiceDiscoveryPage() { }} searchable /> + + o === "active" ? badgeClasses.healthOk : badgeClasses.healthInfo + } + placeholder="Filter by state" + values={(stateFilter?.filter((v) => v !== null) as string[]) || []} + onChange={(values) => setStateFilter(values)} + /> } @@ -118,6 +138,7 @@ export default function ServiceDiscoveryPage() { diff --git a/web/ui/mantine-ui/src/pages/service-discovery/ServiceDiscoveryPoolsList.tsx b/web/ui/mantine-ui/src/pages/service-discovery/ServiceDiscoveryPoolsList.tsx index 306b2732ff..537468944a 100644 --- a/web/ui/mantine-ui/src/pages/service-discovery/ServiceDiscoveryPoolsList.tsx +++ b/web/ui/mantine-ui/src/pages/service-discovery/ServiceDiscoveryPoolsList.tsx @@ -17,7 +17,7 @@ import { Target, TargetsResult, } from "../../api/responseTypes/targets"; -import { FC } from "react"; +import { FC, useMemo } from "react"; import { useAppDispatch, useAppSelector } from "../../state/hooks"; import { setCollapsedPools, @@ -62,10 +62,12 @@ const droppedTargetKVSearch = new KVSearch({ indexedKeys: ["discoveredLabels", ["discoveredLabels", /.*/]], }); -const groupTargets = ( +const buildPoolsData = ( poolNames: string[], activeTargets: Target[], - droppedTargets: DroppedTarget[] + droppedTargets: DroppedTarget[], + search: string, + stateFilter: (string | null)[] ): ScrapePools => { const pools: ScrapePools = {}; @@ -88,8 +90,19 @@ const groupTargets = ( pool.active++; pool.total++; + } - pool.targets.push({ + const filteredActiveTargets = + stateFilter.length !== 0 && !stateFilter.includes("active") + ? [] + : search === "" + ? activeTargets + : activeTargetKVSearch + .filter(search, activeTargets) + .map((value) => value.original); + + for (const target of filteredActiveTargets) { + pools[target.scrapePool].targets.push({ discoveredLabels: target.discoveredLabels, labels: target.labels, isDropped: false, @@ -107,30 +120,39 @@ const groupTargets = ( } pool.total++; + } - pool.targets.push({ + const filteredDroppedTargets = + stateFilter.length !== 0 && !stateFilter.includes("dropped") + ? [] + : search === "" + ? droppedTargets + : droppedTargetKVSearch + .filter(search, droppedTargets) + .map((value) => value.original); + + for (const target of filteredDroppedTargets) { + pools[target.discoveredLabels.job].targets.push({ discoveredLabels: target.discoveredLabels, isDropped: true, labels: {}, }); } - // for (const target of shownTargets) { - // pools[target.scrapePool].targets.push(target); - // } - return pools; }; type ScrapePoolListProp = { poolNames: string[]; selectedPool: string | null; + stateFilter: string[]; searchFilter: string; }; const ScrapePoolList: FC = ({ poolNames, selectedPool, + stateFilter, searchFilter, }) => { const dispatch = useAppDispatch(); @@ -157,24 +179,23 @@ const ScrapePoolList: FC = ({ const [debouncedSearch] = useDebouncedValue(searchFilter, 250); - // TODO: Memoize all this computation, especially groupTargets(). - // const search = debouncedSearch.trim(); - // const healthFilteredTargets = activeTargets.filter( - // (target) => - // healthFilter.length === 0 || - // healthFilter.includes(target.health.toLowerCase()) - // ); - // const filteredTargets = - // search === "" - // ? healthFilteredTargets - // : kvSearch - // .filter(search, healthFilteredTargets) - // .map((value) => value.original); - - const allPools = groupTargets( - selectedPool ? [selectedPool] : poolNames, - activeTargets, - droppedTargets + const allPools = useMemo( + () => + buildPoolsData( + selectedPool ? [selectedPool] : poolNames, + activeTargets, + droppedTargets, + debouncedSearch, + stateFilter + ), + [ + selectedPool, + poolNames, + activeTargets, + droppedTargets, + debouncedSearch, + stateFilter, + ] ); const allPoolNames = Object.keys(allPools); const shownPoolNames = showEmptyPools @@ -240,17 +261,22 @@ const ScrapePoolList: FC = ({ diff --git a/web/ui/mantine-ui/src/pages/targets/ScrapePoolsList.tsx b/web/ui/mantine-ui/src/pages/targets/ScrapePoolsList.tsx index 5f7e5fea22..1e399b8a18 100644 --- a/web/ui/mantine-ui/src/pages/targets/ScrapePoolsList.tsx +++ b/web/ui/mantine-ui/src/pages/targets/ScrapePoolsList.tsx @@ -254,22 +254,24 @@ const ScrapePoolList: FC = ({