mirror of
https://github.com/prometheus/prometheus.git
synced 2025-03-05 20:59:13 -08:00
Make "hide empty rules persistent"
It can be a bit annoying to always press "hide empty rules". This commit uses the session storage of the browser to make it persistent. Signed-off-by: leonnicolas <leonloechner@gmx.de>
This commit is contained in:
parent
0a19f1268e
commit
6ccd9add1e
|
@ -5,7 +5,7 @@ import {
|
|||
Checkbox,
|
||||
Stack,
|
||||
Group,
|
||||
NumberInput,
|
||||
NumberInput
|
||||
} from "@mantine/core";
|
||||
import { IconSettings } from "@tabler/icons-react";
|
||||
import { FC } from "react";
|
||||
|
@ -21,8 +21,9 @@ const SettingsMenu: FC = () => {
|
|||
enableSyntaxHighlighting,
|
||||
enableLinter,
|
||||
showAnnotations,
|
||||
hideEmptyGroups,
|
||||
ruleGroupsPerPage,
|
||||
alertGroupsPerPage,
|
||||
alertGroupsPerPage
|
||||
} = useSettings();
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
|
@ -48,7 +49,7 @@ const SettingsMenu: FC = () => {
|
|||
onChange={(event) =>
|
||||
dispatch(
|
||||
updateSettings({
|
||||
useLocalTime: event.currentTarget.checked,
|
||||
useLocalTime: event.currentTarget.checked
|
||||
})
|
||||
)
|
||||
}
|
||||
|
@ -63,7 +64,7 @@ const SettingsMenu: FC = () => {
|
|||
onChange={(event) =>
|
||||
dispatch(
|
||||
updateSettings({
|
||||
enableQueryHistory: event.currentTarget.checked,
|
||||
enableQueryHistory: event.currentTarget.checked
|
||||
})
|
||||
)
|
||||
}
|
||||
|
@ -74,7 +75,7 @@ const SettingsMenu: FC = () => {
|
|||
onChange={(event) =>
|
||||
dispatch(
|
||||
updateSettings({
|
||||
enableAutocomplete: event.currentTarget.checked,
|
||||
enableAutocomplete: event.currentTarget.checked
|
||||
})
|
||||
)
|
||||
}
|
||||
|
@ -85,7 +86,7 @@ const SettingsMenu: FC = () => {
|
|||
onChange={(event) =>
|
||||
dispatch(
|
||||
updateSettings({
|
||||
enableSyntaxHighlighting: event.currentTarget.checked,
|
||||
enableSyntaxHighlighting: event.currentTarget.checked
|
||||
})
|
||||
)
|
||||
}
|
||||
|
@ -96,7 +97,7 @@ const SettingsMenu: FC = () => {
|
|||
onChange={(event) =>
|
||||
dispatch(
|
||||
updateSettings({
|
||||
enableLinter: event.currentTarget.checked,
|
||||
enableLinter: event.currentTarget.checked
|
||||
})
|
||||
)
|
||||
}
|
||||
|
@ -107,17 +108,30 @@ const SettingsMenu: FC = () => {
|
|||
|
||||
<Stack>
|
||||
<Fieldset p="md" legend="Alerts page settings">
|
||||
<Checkbox
|
||||
checked={showAnnotations}
|
||||
label="Show expanded annotations"
|
||||
onChange={(event) =>
|
||||
dispatch(
|
||||
updateSettings({
|
||||
showAnnotations: event.currentTarget.checked,
|
||||
})
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Stack>
|
||||
<Checkbox
|
||||
checked={showAnnotations}
|
||||
label="Show expanded annotations"
|
||||
onChange={(event) =>
|
||||
dispatch(
|
||||
updateSettings({
|
||||
showAnnotations: event.currentTarget.checked
|
||||
})
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Checkbox
|
||||
checked={hideEmptyGroups}
|
||||
label="Hide empty groups"
|
||||
onChange={(event) =>
|
||||
dispatch(
|
||||
updateSettings({
|
||||
hideEmptyGroups: event.currentTarget.checked
|
||||
})
|
||||
)
|
||||
}
|
||||
/>
|
||||
</Stack>
|
||||
</Fieldset>
|
||||
<Fieldset p="md" legend="Alerts page settings">
|
||||
<NumberInput
|
||||
|
@ -132,7 +146,7 @@ const SettingsMenu: FC = () => {
|
|||
|
||||
dispatch(
|
||||
updateSettings({
|
||||
alertGroupsPerPage: value,
|
||||
alertGroupsPerPage: value
|
||||
})
|
||||
);
|
||||
}}
|
||||
|
@ -151,7 +165,7 @@ const SettingsMenu: FC = () => {
|
|||
|
||||
dispatch(
|
||||
updateSettings({
|
||||
ruleGroupsPerPage: value,
|
||||
ruleGroupsPerPage: value
|
||||
})
|
||||
);
|
||||
}}
|
||||
|
|
|
@ -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";
|
||||
|
@ -23,14 +23,14 @@ import { Fragment, useEffect, useMemo } from "react";
|
|||
import { StateMultiSelect } from "../components/StateMultiSelect";
|
||||
import { IconInfoCircle, IconSearch } from "@tabler/icons-react";
|
||||
import { LabelBadges } from "../components/LabelBadges";
|
||||
import { useSettings } from "../state/settingsSlice";
|
||||
import { useSettings, updateSettings } from "../state/settingsSlice";
|
||||
import { useAppDispatch } from "../state/hooks";
|
||||
import {
|
||||
ArrayParam,
|
||||
BooleanParam,
|
||||
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<AlertingRule>({
|
||||
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,11 +146,12 @@ export default function AlertsPage() {
|
|||
const { data } = useSuspenseAPIQuery<AlertingRulesResult>({
|
||||
path: `/rules`,
|
||||
params: {
|
||||
type: "alert",
|
||||
},
|
||||
type: "alert"
|
||||
}
|
||||
});
|
||||
|
||||
const { showAnnotations } = useSettings();
|
||||
const { hideEmptyGroups, showAnnotations } = useSettings();
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
// Define URL query params.
|
||||
const [stateFilter, setStateFilter] = useQueryParam(
|
||||
|
@ -162,10 +163,6 @@ export default function AlertsPage() {
|
|||
withDefault(StringParam, "")
|
||||
);
|
||||
const [debouncedSearch] = useDebouncedValue<string>(searchFilter.trim(), 250);
|
||||
const [showEmptyGroups, setShowEmptyGroups] = useQueryParam(
|
||||
"showEmptyGroups",
|
||||
withDefault(BooleanParam, true)
|
||||
);
|
||||
|
||||
const { alertGroupsPerPage } = useSettings();
|
||||
const [activePage, setActivePage] = useQueryParam(
|
||||
|
@ -181,10 +178,10 @@ export default function AlertsPage() {
|
|||
|
||||
const shownGroups = useMemo(
|
||||
() =>
|
||||
showEmptyGroups
|
||||
!hideEmptyGroups
|
||||
? alertsPageData.groups
|
||||
: alertsPageData.groups.filter((g) => g.rules.length > 0),
|
||||
[alertsPageData.groups, showEmptyGroups]
|
||||
[alertsPageData.groups, hideEmptyGroups]
|
||||
);
|
||||
|
||||
// If we were e.g. on page 10 and the number of total pages decreases to 5 (due to filtering
|
||||
|
@ -255,7 +252,13 @@ export default function AlertsPage() {
|
|||
<Anchor
|
||||
ml="md"
|
||||
fz="1em"
|
||||
onClick={() => setShowEmptyGroups(false)}
|
||||
onClick={() => {
|
||||
dispatch(
|
||||
updateSettings({
|
||||
hideEmptyGroups: true
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
Hide empty groups
|
||||
</Anchor>
|
||||
|
@ -267,7 +270,13 @@ export default function AlertsPage() {
|
|||
<Anchor
|
||||
ml="md"
|
||||
fz="1em"
|
||||
onClick={() => setShowEmptyGroups(false)}
|
||||
onClick={() => {
|
||||
dispatch(
|
||||
updateSettings({
|
||||
hideEmptyGroups: true
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
Hide empty groups
|
||||
</Anchor>
|
||||
|
@ -286,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()}
|
||||
|
@ -403,7 +412,7 @@ export default function AlertsPage() {
|
|||
)}
|
||||
</Card>
|
||||
)),
|
||||
[currentPageGroups, showAnnotations, setShowEmptyGroups]
|
||||
[currentPageGroups, showAnnotations, dispatch]
|
||||
);
|
||||
|
||||
return (
|
||||
|
@ -442,7 +451,7 @@ export default function AlertsPage() {
|
|||
No rules found.
|
||||
</Alert>
|
||||
) : (
|
||||
!showEmptyGroups &&
|
||||
hideEmptyGroups &&
|
||||
alertsPageData.groups.length !== shownGroups.length && (
|
||||
<Alert
|
||||
title="Hiding groups with no matching rules"
|
||||
|
@ -450,7 +459,13 @@ export default function AlertsPage() {
|
|||
>
|
||||
Hiding {alertsPageData.groups.length - shownGroups.length} empty
|
||||
groups due to filters or no rules.
|
||||
<Anchor ml="md" fz="1em" onClick={() => setShowEmptyGroups(true)}>
|
||||
<Anchor
|
||||
ml="md"
|
||||
fz="1em"
|
||||
onClick={() =>
|
||||
dispatch(updateSettings({ hideEmptyGroups: false }))
|
||||
}
|
||||
>
|
||||
Show empty groups
|
||||
</Anchor>
|
||||
</Alert>
|
||||
|
|
|
@ -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,
|
||||
);
|
||||
},
|
||||
});
|
||||
|
@ -62,6 +62,7 @@ startAppListening({
|
|||
case "enableAutocomplete":
|
||||
case "enableSyntaxHighlighting":
|
||||
case "enableLinter":
|
||||
case "hideEmptyGroups":
|
||||
case "showAnnotations":
|
||||
case "ruleGroupsPerPage":
|
||||
return persistToLocalStorage(`settings.${key}`, value);
|
||||
|
|
|
@ -13,6 +13,7 @@ interface Settings {
|
|||
enableAutocomplete: boolean;
|
||||
enableSyntaxHighlighting: boolean;
|
||||
enableLinter: boolean;
|
||||
hideEmptyGroups: boolean;
|
||||
showAnnotations: boolean;
|
||||
ruleGroupsPerPage: number;
|
||||
alertGroupsPerPage: number;
|
||||
|
@ -30,6 +31,7 @@ export const localStorageKeyEnableAutocomplete = "settings.enableAutocomplete";
|
|||
export const localStorageKeyEnableSyntaxHighlighting =
|
||||
"settings.enableSyntaxHighlighting";
|
||||
export const localStorageKeyEnableLinter = "settings.enableLinter";
|
||||
export const localStorageKeyHideEmptyGroups = "settings.hideEmptyGroups";
|
||||
export const localStorageKeyShowAnnotations = "settings.showAnnotations";
|
||||
export const localStorageKeyRuleGroupsPerPage = "settings.ruleGroupsPerPage";
|
||||
export const localStorageKeyAlertGroupsPerPage = "settings.alertGroupsPerPage";
|
||||
|
@ -53,7 +55,7 @@ const getPathPrefix = (path: string) => {
|
|||
"/flags",
|
||||
"/config",
|
||||
"/alertmanager-discovery",
|
||||
"/agent",
|
||||
"/agent"
|
||||
];
|
||||
|
||||
const pagePath = pagePaths.find((p) => path.endsWith(p));
|
||||
|
@ -95,6 +97,10 @@ export const initialState: Settings = {
|
|||
localStorageKeyEnableLinter,
|
||||
true
|
||||
),
|
||||
hideEmptyGroups: initializeFromLocalStorage<boolean>(
|
||||
localStorageKeyHideEmptyGroups,
|
||||
false
|
||||
),
|
||||
showAnnotations: initializeFromLocalStorage<boolean>(
|
||||
localStorageKeyShowAnnotations,
|
||||
true
|
||||
|
@ -106,7 +112,7 @@ export const initialState: Settings = {
|
|||
alertGroupsPerPage: initializeFromLocalStorage<number>(
|
||||
localStorageKeyAlertGroupsPerPage,
|
||||
10
|
||||
),
|
||||
)
|
||||
};
|
||||
|
||||
export const settingsSlice = createSlice({
|
||||
|
@ -115,8 +121,8 @@ export const settingsSlice = createSlice({
|
|||
reducers: {
|
||||
updateSettings: (state, { payload }: PayloadAction<Partial<Settings>>) => {
|
||||
Object.assign(state, payload);
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export const { updateSettings } = settingsSlice.actions;
|
||||
|
|
Loading…
Reference in a new issue