From b3531a12f333cdf0b290f60898447eb8681f151a Mon Sep 17 00:00:00 2001 From: leonnicolas Date: Mon, 13 Jan 2025 09:37:44 +0100 Subject: [PATCH] Make "show empty pools" setting persistent Just like for showing empty groups on the Alerts page, also make the setting for showing empty pools on the Targets page persistent. Signed-off-by: leonnicolas --- .../src/components/SettingsMenu.tsx | 36 +++++++++++++------ web/ui/mantine-ui/src/pages/AlertsPage.tsx | 30 ++++++++-------- .../src/pages/targets/ScrapePoolsList.tsx | 21 ++++++----- .../src/state/localStorageMiddleware.ts | 5 +-- web/ui/mantine-ui/src/state/settingsSlice.ts | 14 +++++--- 5 files changed, 66 insertions(+), 40 deletions(-) diff --git a/web/ui/mantine-ui/src/components/SettingsMenu.tsx b/web/ui/mantine-ui/src/components/SettingsMenu.tsx index 79d9c201c..d7fe458ca 100644 --- a/web/ui/mantine-ui/src/components/SettingsMenu.tsx +++ b/web/ui/mantine-ui/src/components/SettingsMenu.tsx @@ -5,7 +5,7 @@ import { Checkbox, Stack, Group, - NumberInput + NumberInput, } from "@mantine/core"; import { IconSettings } from "@tabler/icons-react"; import { FC } from "react"; @@ -23,7 +23,8 @@ const SettingsMenu: FC = () => { showAnnotations, hideEmptyGroups, ruleGroupsPerPage, - alertGroupsPerPage + alertGroupsPerPage, + showEmptyPools, } = useSettings(); const dispatch = useAppDispatch(); @@ -49,7 +50,7 @@ const SettingsMenu: FC = () => { onChange={(event) => dispatch( updateSettings({ - useLocalTime: event.currentTarget.checked + useLocalTime: event.currentTarget.checked, }) ) } @@ -64,7 +65,7 @@ const SettingsMenu: FC = () => { onChange={(event) => dispatch( updateSettings({ - enableQueryHistory: event.currentTarget.checked + enableQueryHistory: event.currentTarget.checked, }) ) } @@ -75,7 +76,7 @@ const SettingsMenu: FC = () => { onChange={(event) => dispatch( updateSettings({ - enableAutocomplete: event.currentTarget.checked + enableAutocomplete: event.currentTarget.checked, }) ) } @@ -86,7 +87,7 @@ const SettingsMenu: FC = () => { onChange={(event) => dispatch( updateSettings({ - enableSyntaxHighlighting: event.currentTarget.checked + enableSyntaxHighlighting: event.currentTarget.checked, }) ) } @@ -97,13 +98,26 @@ const SettingsMenu: FC = () => { onChange={(event) => dispatch( updateSettings({ - enableLinter: event.currentTarget.checked + enableLinter: event.currentTarget.checked, }) ) } /> +
+ + dispatch( + updateSettings({ + showEmptyPools: event.currentTarget.checked, + }) + ) + } + /> +
@@ -115,7 +129,7 @@ const SettingsMenu: FC = () => { onChange={(event) => dispatch( updateSettings({ - showAnnotations: event.currentTarget.checked + showAnnotations: event.currentTarget.checked, }) ) } @@ -126,7 +140,7 @@ const SettingsMenu: FC = () => { onChange={(event) => dispatch( updateSettings({ - hideEmptyGroups: event.currentTarget.checked + hideEmptyGroups: event.currentTarget.checked, }) ) } @@ -146,7 +160,7 @@ const SettingsMenu: FC = () => { dispatch( updateSettings({ - alertGroupsPerPage: value + alertGroupsPerPage: value, }) ); }} @@ -165,7 +179,7 @@ const SettingsMenu: FC = () => { dispatch( updateSettings({ - ruleGroupsPerPage: value + ruleGroupsPerPage: value, }) ); }} diff --git a/web/ui/mantine-ui/src/pages/AlertsPage.tsx b/web/ui/mantine-ui/src/pages/AlertsPage.tsx index 33e170556..69c4d7f13 100644 --- a/web/ui/mantine-ui/src/pages/AlertsPage.tsx +++ b/web/ui/mantine-ui/src/pages/AlertsPage.tsx @@ -11,7 +11,7 @@ import { Alert, TextInput, Anchor, - Pagination + Pagination, } from "@mantine/core"; import { useSuspenseAPIQuery } from "../api/api"; import { AlertingRule, AlertingRulesResult } from "../api/responseTypes/rules"; @@ -30,7 +30,7 @@ import { NumberParam, StringParam, useQueryParam, - withDefault + withDefault, } from "use-query-params"; import { useDebouncedValue } from "@mantine/hooks"; import { KVSearch } from "@nexucis/kvsearch"; @@ -67,7 +67,7 @@ type AlertsPageData = { const kvSearch = new KVSearch({ shouldSort: true, - indexedKeys: ["name", "labels", ["labels", /.*/]] + indexedKeys: ["name", "labels", ["labels", /.*/]], }); const buildAlertsPageData = ( @@ -79,9 +79,9 @@ const buildAlertsPageData = ( globalCounts: { inactive: 0, pending: 0, - firing: 0 + firing: 0, }, - groups: [] + groups: [], }; for (const group of data.groups) { @@ -89,7 +89,7 @@ const buildAlertsPageData = ( total: 0, inactive: 0, pending: 0, - firing: 0 + firing: 0, }; for (const r of group.rules) { @@ -126,9 +126,9 @@ const buildAlertsPageData = ( rule: r, counts: { firing: r.alerts.filter((a) => a.state === "firing").length, - pending: r.alerts.filter((a) => a.state === "pending").length - } - })) + pending: r.alerts.filter((a) => a.state === "pending").length, + }, + })), }); } @@ -146,8 +146,8 @@ export default function AlertsPage() { const { data } = useSuspenseAPIQuery({ path: `/rules`, params: { - type: "alert" - } + type: "alert", + }, }); const { hideEmptyGroups, showAnnotations } = useSettings(); @@ -255,7 +255,7 @@ export default function AlertsPage() { onClick={() => { dispatch( updateSettings({ - hideEmptyGroups: true + hideEmptyGroups: true, }) ); }} @@ -273,7 +273,7 @@ export default function AlertsPage() { onClick={() => { dispatch( updateSettings({ - hideEmptyGroups: true + hideEmptyGroups: true, }) ); }} @@ -295,8 +295,8 @@ export default function AlertsPage() { // have a different background color than their surrounding group card in dark mode, // but it would be better to use CSS to override the light/dark colors for // collapsed/expanded accordion items. - backgroundColor: "#c0c0c015" - } + backgroundColor: "#c0c0c015", + }, }} key={j} value={j.toString()} diff --git a/web/ui/mantine-ui/src/pages/targets/ScrapePoolsList.tsx b/web/ui/mantine-ui/src/pages/targets/ScrapePoolsList.tsx index be91b149b..68c1db184 100644 --- a/web/ui/mantine-ui/src/pages/targets/ScrapePoolsList.tsx +++ b/web/ui/mantine-ui/src/pages/targets/ScrapePoolsList.tsx @@ -30,6 +30,7 @@ import { setCollapsedPools, setShowLimitAlert, } from "../../state/targetsPageSlice"; +import { useSettings, updateSettings } from "../../state/settingsSlice"; import EndpointLink from "../../components/EndpointLink"; import CustomInfiniteScroll from "../../components/CustomInfiniteScroll"; @@ -38,7 +39,6 @@ import panelClasses from "../../Panel.module.css"; import TargetLabels from "./TargetLabels"; import { useDebouncedValue } from "@mantine/hooks"; import { targetPoolDisplayLimit } from "./TargetsPage"; -import { BooleanParam, useQueryParam, withDefault } from "use-query-params"; import { badgeIconStyle } from "../../styles"; type ScrapePool = { @@ -164,11 +164,8 @@ const ScrapePoolList: FC = ({ }, }); + const { showEmptyPools } = useSettings(); const dispatch = useAppDispatch(); - const [showEmptyPools, setShowEmptyPools] = useQueryParam( - "showEmptyPools", - withDefault(BooleanParam, true) - ); const { collapsedPools, showLimitAlert } = useAppSelector( (state) => state.targetsPage @@ -207,7 +204,11 @@ const ScrapePoolList: FC = ({ > Hiding {allPoolNames.length - shownPoolNames.length} empty pools due to filters or no targets. - setShowEmptyPools(true)}> + dispatch(updateSettings({ showEmptyPools: true }))} + > Show empty pools @@ -281,7 +282,9 @@ const ScrapePoolList: FC = ({ setShowEmptyPools(false)} + onClick={() => + dispatch(updateSettings({ showEmptyPools: false })) + } > Hide empty pools @@ -293,7 +296,9 @@ const ScrapePoolList: FC = ({ setShowEmptyPools(false)} + onClick={() => + dispatch(updateSettings({ showEmptyPools: false })) + } > Hide empty pools diff --git a/web/ui/mantine-ui/src/state/localStorageMiddleware.ts b/web/ui/mantine-ui/src/state/localStorageMiddleware.ts index b3dc70662..e27e85844 100644 --- a/web/ui/mantine-ui/src/state/localStorageMiddleware.ts +++ b/web/ui/mantine-ui/src/state/localStorageMiddleware.ts @@ -37,7 +37,7 @@ startAppListening({ effect: ({ payload }) => { persistToLocalStorage( localStorageKeyServiceDiscoveryPageCollapsedPools, - payload, + payload ); }, }); @@ -47,7 +47,7 @@ startAppListening({ effect: (_, { getState }) => { persistToLocalStorage( localStorageKeyQueryHistory, - getState().queryPage.queryHistory, + getState().queryPage.queryHistory ); }, }); @@ -65,6 +65,7 @@ startAppListening({ case "hideEmptyGroups": case "showAnnotations": case "ruleGroupsPerPage": + case "showEmptyPools": return persistToLocalStorage(`settings.${key}`, value); } }); diff --git a/web/ui/mantine-ui/src/state/settingsSlice.ts b/web/ui/mantine-ui/src/state/settingsSlice.ts index da1c1546b..06b4c06ca 100644 --- a/web/ui/mantine-ui/src/state/settingsSlice.ts +++ b/web/ui/mantine-ui/src/state/settingsSlice.ts @@ -17,6 +17,7 @@ interface Settings { showAnnotations: boolean; ruleGroupsPerPage: number; alertGroupsPerPage: number; + showEmptyPools: boolean; } // Declared/defined in public/index.html, value replaced by Prometheus when serving bundle. @@ -35,6 +36,7 @@ export const localStorageKeyHideEmptyGroups = "settings.hideEmptyGroups"; export const localStorageKeyShowAnnotations = "settings.showAnnotations"; export const localStorageKeyRuleGroupsPerPage = "settings.ruleGroupsPerPage"; export const localStorageKeyAlertGroupsPerPage = "settings.alertGroupsPerPage"; +export const localStorageKeyShowEmptyPools = "settings.showEmptyPools"; // This dynamically/generically determines the pathPrefix by stripping the first known // endpoint suffix from the window location path. It works out of the box for both direct @@ -55,7 +57,7 @@ const getPathPrefix = (path: string) => { "/flags", "/config", "/alertmanager-discovery", - "/agent" + "/agent", ]; const pagePath = pagePaths.find((p) => path.endsWith(p)); @@ -112,7 +114,11 @@ export const initialState: Settings = { alertGroupsPerPage: initializeFromLocalStorage( localStorageKeyAlertGroupsPerPage, 10 - ) + ), + showEmptyPools: initializeFromLocalStorage( + localStorageKeyShowEmptyPools, + true + ), }; export const settingsSlice = createSlice({ @@ -121,8 +127,8 @@ export const settingsSlice = createSlice({ reducers: { updateSettings: (state, { payload }: PayloadAction>) => { Object.assign(state, payload); - } - } + }, + }, }); export const { updateSettings } = settingsSlice.actions;