mirror of https://github.com/prometheus/prometheus
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 <leonloechner@gmx.de>pull/15807/head
parent
6ccd9add1e
commit
b3531a12f3
|
@ -5,7 +5,7 @@ import {
|
||||||
Checkbox,
|
Checkbox,
|
||||||
Stack,
|
Stack,
|
||||||
Group,
|
Group,
|
||||||
NumberInput
|
NumberInput,
|
||||||
} from "@mantine/core";
|
} from "@mantine/core";
|
||||||
import { IconSettings } from "@tabler/icons-react";
|
import { IconSettings } from "@tabler/icons-react";
|
||||||
import { FC } from "react";
|
import { FC } from "react";
|
||||||
|
@ -23,7 +23,8 @@ const SettingsMenu: FC = () => {
|
||||||
showAnnotations,
|
showAnnotations,
|
||||||
hideEmptyGroups,
|
hideEmptyGroups,
|
||||||
ruleGroupsPerPage,
|
ruleGroupsPerPage,
|
||||||
alertGroupsPerPage
|
alertGroupsPerPage,
|
||||||
|
showEmptyPools,
|
||||||
} = useSettings();
|
} = useSettings();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
|
@ -49,7 +50,7 @@ const SettingsMenu: FC = () => {
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
dispatch(
|
dispatch(
|
||||||
updateSettings({
|
updateSettings({
|
||||||
useLocalTime: event.currentTarget.checked
|
useLocalTime: event.currentTarget.checked,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -64,7 +65,7 @@ const SettingsMenu: FC = () => {
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
dispatch(
|
dispatch(
|
||||||
updateSettings({
|
updateSettings({
|
||||||
enableQueryHistory: event.currentTarget.checked
|
enableQueryHistory: event.currentTarget.checked,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -75,7 +76,7 @@ const SettingsMenu: FC = () => {
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
dispatch(
|
dispatch(
|
||||||
updateSettings({
|
updateSettings({
|
||||||
enableAutocomplete: event.currentTarget.checked
|
enableAutocomplete: event.currentTarget.checked,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -86,7 +87,7 @@ const SettingsMenu: FC = () => {
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
dispatch(
|
dispatch(
|
||||||
updateSettings({
|
updateSettings({
|
||||||
enableSyntaxHighlighting: event.currentTarget.checked
|
enableSyntaxHighlighting: event.currentTarget.checked,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -97,13 +98,26 @@ const SettingsMenu: FC = () => {
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
dispatch(
|
dispatch(
|
||||||
updateSettings({
|
updateSettings({
|
||||||
enableLinter: event.currentTarget.checked
|
enableLinter: event.currentTarget.checked,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Fieldset>
|
</Fieldset>
|
||||||
|
<Fieldset p="md" legend="Targets page settings">
|
||||||
|
<Checkbox
|
||||||
|
checked={showEmptyPools}
|
||||||
|
label="Show empty pools"
|
||||||
|
onChange={(event) =>
|
||||||
|
dispatch(
|
||||||
|
updateSettings({
|
||||||
|
showEmptyPools: event.currentTarget.checked,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Fieldset>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
<Stack>
|
<Stack>
|
||||||
|
@ -115,7 +129,7 @@ const SettingsMenu: FC = () => {
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
dispatch(
|
dispatch(
|
||||||
updateSettings({
|
updateSettings({
|
||||||
showAnnotations: event.currentTarget.checked
|
showAnnotations: event.currentTarget.checked,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -126,7 +140,7 @@ const SettingsMenu: FC = () => {
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
dispatch(
|
dispatch(
|
||||||
updateSettings({
|
updateSettings({
|
||||||
hideEmptyGroups: event.currentTarget.checked
|
hideEmptyGroups: event.currentTarget.checked,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -146,7 +160,7 @@ const SettingsMenu: FC = () => {
|
||||||
|
|
||||||
dispatch(
|
dispatch(
|
||||||
updateSettings({
|
updateSettings({
|
||||||
alertGroupsPerPage: value
|
alertGroupsPerPage: value,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
|
@ -165,7 +179,7 @@ const SettingsMenu: FC = () => {
|
||||||
|
|
||||||
dispatch(
|
dispatch(
|
||||||
updateSettings({
|
updateSettings({
|
||||||
ruleGroupsPerPage: value
|
ruleGroupsPerPage: value,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -11,7 +11,7 @@ import {
|
||||||
Alert,
|
Alert,
|
||||||
TextInput,
|
TextInput,
|
||||||
Anchor,
|
Anchor,
|
||||||
Pagination
|
Pagination,
|
||||||
} from "@mantine/core";
|
} from "@mantine/core";
|
||||||
import { useSuspenseAPIQuery } from "../api/api";
|
import { useSuspenseAPIQuery } from "../api/api";
|
||||||
import { AlertingRule, AlertingRulesResult } from "../api/responseTypes/rules";
|
import { AlertingRule, AlertingRulesResult } from "../api/responseTypes/rules";
|
||||||
|
@ -30,7 +30,7 @@ import {
|
||||||
NumberParam,
|
NumberParam,
|
||||||
StringParam,
|
StringParam,
|
||||||
useQueryParam,
|
useQueryParam,
|
||||||
withDefault
|
withDefault,
|
||||||
} from "use-query-params";
|
} from "use-query-params";
|
||||||
import { useDebouncedValue } from "@mantine/hooks";
|
import { useDebouncedValue } from "@mantine/hooks";
|
||||||
import { KVSearch } from "@nexucis/kvsearch";
|
import { KVSearch } from "@nexucis/kvsearch";
|
||||||
|
@ -67,7 +67,7 @@ type AlertsPageData = {
|
||||||
|
|
||||||
const kvSearch = new KVSearch<AlertingRule>({
|
const kvSearch = new KVSearch<AlertingRule>({
|
||||||
shouldSort: true,
|
shouldSort: true,
|
||||||
indexedKeys: ["name", "labels", ["labels", /.*/]]
|
indexedKeys: ["name", "labels", ["labels", /.*/]],
|
||||||
});
|
});
|
||||||
|
|
||||||
const buildAlertsPageData = (
|
const buildAlertsPageData = (
|
||||||
|
@ -79,9 +79,9 @@ const buildAlertsPageData = (
|
||||||
globalCounts: {
|
globalCounts: {
|
||||||
inactive: 0,
|
inactive: 0,
|
||||||
pending: 0,
|
pending: 0,
|
||||||
firing: 0
|
firing: 0,
|
||||||
},
|
},
|
||||||
groups: []
|
groups: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const group of data.groups) {
|
for (const group of data.groups) {
|
||||||
|
@ -89,7 +89,7 @@ const buildAlertsPageData = (
|
||||||
total: 0,
|
total: 0,
|
||||||
inactive: 0,
|
inactive: 0,
|
||||||
pending: 0,
|
pending: 0,
|
||||||
firing: 0
|
firing: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const r of group.rules) {
|
for (const r of group.rules) {
|
||||||
|
@ -126,9 +126,9 @@ const buildAlertsPageData = (
|
||||||
rule: r,
|
rule: r,
|
||||||
counts: {
|
counts: {
|
||||||
firing: r.alerts.filter((a) => a.state === "firing").length,
|
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<AlertingRulesResult>({
|
const { data } = useSuspenseAPIQuery<AlertingRulesResult>({
|
||||||
path: `/rules`,
|
path: `/rules`,
|
||||||
params: {
|
params: {
|
||||||
type: "alert"
|
type: "alert",
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const { hideEmptyGroups, showAnnotations } = useSettings();
|
const { hideEmptyGroups, showAnnotations } = useSettings();
|
||||||
|
@ -255,7 +255,7 @@ export default function AlertsPage() {
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
dispatch(
|
dispatch(
|
||||||
updateSettings({
|
updateSettings({
|
||||||
hideEmptyGroups: true
|
hideEmptyGroups: true,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
|
@ -273,7 +273,7 @@ export default function AlertsPage() {
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
dispatch(
|
dispatch(
|
||||||
updateSettings({
|
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,
|
// 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
|
// but it would be better to use CSS to override the light/dark colors for
|
||||||
// collapsed/expanded accordion items.
|
// collapsed/expanded accordion items.
|
||||||
backgroundColor: "#c0c0c015"
|
backgroundColor: "#c0c0c015",
|
||||||
}
|
},
|
||||||
}}
|
}}
|
||||||
key={j}
|
key={j}
|
||||||
value={j.toString()}
|
value={j.toString()}
|
||||||
|
|
|
@ -30,6 +30,7 @@ import {
|
||||||
setCollapsedPools,
|
setCollapsedPools,
|
||||||
setShowLimitAlert,
|
setShowLimitAlert,
|
||||||
} from "../../state/targetsPageSlice";
|
} from "../../state/targetsPageSlice";
|
||||||
|
import { useSettings, updateSettings } from "../../state/settingsSlice";
|
||||||
import EndpointLink from "../../components/EndpointLink";
|
import EndpointLink from "../../components/EndpointLink";
|
||||||
import CustomInfiniteScroll from "../../components/CustomInfiniteScroll";
|
import CustomInfiniteScroll from "../../components/CustomInfiniteScroll";
|
||||||
|
|
||||||
|
@ -38,7 +39,6 @@ import panelClasses from "../../Panel.module.css";
|
||||||
import TargetLabels from "./TargetLabels";
|
import TargetLabels from "./TargetLabels";
|
||||||
import { useDebouncedValue } from "@mantine/hooks";
|
import { useDebouncedValue } from "@mantine/hooks";
|
||||||
import { targetPoolDisplayLimit } from "./TargetsPage";
|
import { targetPoolDisplayLimit } from "./TargetsPage";
|
||||||
import { BooleanParam, useQueryParam, withDefault } from "use-query-params";
|
|
||||||
import { badgeIconStyle } from "../../styles";
|
import { badgeIconStyle } from "../../styles";
|
||||||
|
|
||||||
type ScrapePool = {
|
type ScrapePool = {
|
||||||
|
@ -164,11 +164,8 @@ const ScrapePoolList: FC<ScrapePoolListProp> = ({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const { showEmptyPools } = useSettings();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const [showEmptyPools, setShowEmptyPools] = useQueryParam(
|
|
||||||
"showEmptyPools",
|
|
||||||
withDefault(BooleanParam, true)
|
|
||||||
);
|
|
||||||
|
|
||||||
const { collapsedPools, showLimitAlert } = useAppSelector(
|
const { collapsedPools, showLimitAlert } = useAppSelector(
|
||||||
(state) => state.targetsPage
|
(state) => state.targetsPage
|
||||||
|
@ -207,7 +204,11 @@ const ScrapePoolList: FC<ScrapePoolListProp> = ({
|
||||||
>
|
>
|
||||||
Hiding {allPoolNames.length - shownPoolNames.length} empty pools due
|
Hiding {allPoolNames.length - shownPoolNames.length} empty pools due
|
||||||
to filters or no targets.
|
to filters or no targets.
|
||||||
<Anchor ml="md" fz="1em" onClick={() => setShowEmptyPools(true)}>
|
<Anchor
|
||||||
|
ml="md"
|
||||||
|
fz="1em"
|
||||||
|
onClick={() => dispatch(updateSettings({ showEmptyPools: true }))}
|
||||||
|
>
|
||||||
Show empty pools
|
Show empty pools
|
||||||
</Anchor>
|
</Anchor>
|
||||||
</Alert>
|
</Alert>
|
||||||
|
@ -281,7 +282,9 @@ const ScrapePoolList: FC<ScrapePoolListProp> = ({
|
||||||
<Anchor
|
<Anchor
|
||||||
ml="md"
|
ml="md"
|
||||||
fz="1em"
|
fz="1em"
|
||||||
onClick={() => setShowEmptyPools(false)}
|
onClick={() =>
|
||||||
|
dispatch(updateSettings({ showEmptyPools: false }))
|
||||||
|
}
|
||||||
>
|
>
|
||||||
Hide empty pools
|
Hide empty pools
|
||||||
</Anchor>
|
</Anchor>
|
||||||
|
@ -293,7 +296,9 @@ const ScrapePoolList: FC<ScrapePoolListProp> = ({
|
||||||
<Anchor
|
<Anchor
|
||||||
ml="md"
|
ml="md"
|
||||||
fz="1em"
|
fz="1em"
|
||||||
onClick={() => setShowEmptyPools(false)}
|
onClick={() =>
|
||||||
|
dispatch(updateSettings({ showEmptyPools: false }))
|
||||||
|
}
|
||||||
>
|
>
|
||||||
Hide empty pools
|
Hide empty pools
|
||||||
</Anchor>
|
</Anchor>
|
||||||
|
|
|
@ -37,7 +37,7 @@ startAppListening({
|
||||||
effect: ({ payload }) => {
|
effect: ({ payload }) => {
|
||||||
persistToLocalStorage(
|
persistToLocalStorage(
|
||||||
localStorageKeyServiceDiscoveryPageCollapsedPools,
|
localStorageKeyServiceDiscoveryPageCollapsedPools,
|
||||||
payload,
|
payload
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -47,7 +47,7 @@ startAppListening({
|
||||||
effect: (_, { getState }) => {
|
effect: (_, { getState }) => {
|
||||||
persistToLocalStorage(
|
persistToLocalStorage(
|
||||||
localStorageKeyQueryHistory,
|
localStorageKeyQueryHistory,
|
||||||
getState().queryPage.queryHistory,
|
getState().queryPage.queryHistory
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -65,6 +65,7 @@ startAppListening({
|
||||||
case "hideEmptyGroups":
|
case "hideEmptyGroups":
|
||||||
case "showAnnotations":
|
case "showAnnotations":
|
||||||
case "ruleGroupsPerPage":
|
case "ruleGroupsPerPage":
|
||||||
|
case "showEmptyPools":
|
||||||
return persistToLocalStorage(`settings.${key}`, value);
|
return persistToLocalStorage(`settings.${key}`, value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -17,6 +17,7 @@ interface Settings {
|
||||||
showAnnotations: boolean;
|
showAnnotations: boolean;
|
||||||
ruleGroupsPerPage: number;
|
ruleGroupsPerPage: number;
|
||||||
alertGroupsPerPage: number;
|
alertGroupsPerPage: number;
|
||||||
|
showEmptyPools: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Declared/defined in public/index.html, value replaced by Prometheus when serving bundle.
|
// 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 localStorageKeyShowAnnotations = "settings.showAnnotations";
|
||||||
export const localStorageKeyRuleGroupsPerPage = "settings.ruleGroupsPerPage";
|
export const localStorageKeyRuleGroupsPerPage = "settings.ruleGroupsPerPage";
|
||||||
export const localStorageKeyAlertGroupsPerPage = "settings.alertGroupsPerPage";
|
export const localStorageKeyAlertGroupsPerPage = "settings.alertGroupsPerPage";
|
||||||
|
export const localStorageKeyShowEmptyPools = "settings.showEmptyPools";
|
||||||
|
|
||||||
// This dynamically/generically determines the pathPrefix by stripping the first known
|
// 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
|
// 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",
|
"/flags",
|
||||||
"/config",
|
"/config",
|
||||||
"/alertmanager-discovery",
|
"/alertmanager-discovery",
|
||||||
"/agent"
|
"/agent",
|
||||||
];
|
];
|
||||||
|
|
||||||
const pagePath = pagePaths.find((p) => path.endsWith(p));
|
const pagePath = pagePaths.find((p) => path.endsWith(p));
|
||||||
|
@ -112,7 +114,11 @@ export const initialState: Settings = {
|
||||||
alertGroupsPerPage: initializeFromLocalStorage<number>(
|
alertGroupsPerPage: initializeFromLocalStorage<number>(
|
||||||
localStorageKeyAlertGroupsPerPage,
|
localStorageKeyAlertGroupsPerPage,
|
||||||
10
|
10
|
||||||
)
|
),
|
||||||
|
showEmptyPools: initializeFromLocalStorage<boolean>(
|
||||||
|
localStorageKeyShowEmptyPools,
|
||||||
|
true
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
export const settingsSlice = createSlice({
|
export const settingsSlice = createSlice({
|
||||||
|
@ -121,8 +127,8 @@ export const settingsSlice = createSlice({
|
||||||
reducers: {
|
reducers: {
|
||||||
updateSettings: (state, { payload }: PayloadAction<Partial<Settings>>) => {
|
updateSettings: (state, { payload }: PayloadAction<Partial<Settings>>) => {
|
||||||
Object.assign(state, payload);
|
Object.assign(state, payload);
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const { updateSettings } = settingsSlice.actions;
|
export const { updateSettings } = settingsSlice.actions;
|
||||||
|
|
Loading…
Reference in New Issue