mirror of
https://github.com/prometheus/prometheus.git
synced 2025-03-05 20:59:13 -08:00
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>
This commit is contained in:
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 a new issue