Clean up file hierarchy a bit, add some more comments

Signed-off-by: Julius Volz <julius.volz@gmail.com>
This commit is contained in:
Julius Volz 2024-04-09 12:36:53 +02:00
parent b778c0a249
commit 1049c90cb5
24 changed files with 47 additions and 29 deletions

View file

@ -56,13 +56,13 @@ import FlagsPage from "./pages/FlagsPage";
import ConfigPage from "./pages/ConfigPage";
import AgentPage from "./pages/AgentPage";
import { Suspense, useContext } from "react";
import ErrorBoundary from "./ErrorBoundary";
import { ThemeSelector } from "./ThemeSelector";
import ErrorBoundary from "./components/ErrorBoundary";
import { ThemeSelector } from "./components/ThemeSelector";
import { SettingsContext } from "./settings";
import { Notifications } from "@mantine/notifications";
import { useAppDispatch } from "./state/hooks";
import { updateSettings } from "./state/settingsSlice";
import SettingsMenu from "./SettingsMenu";
import SettingsMenu from "./components/SettingsMenu";
const queryClient = new QueryClient();

View file

@ -1,3 +1,5 @@
// Result type for /api/v1/status/config endpoint.
// See: https://prometheus.io/docs/prometheus/latest/querying/api/#config
export default interface ConfigResult {
yaml: string;
}

View file

@ -1 +1,3 @@
// Result type for /api/v1/label/<label_name>/values endpoint.
// See: https://prometheus.io/docs/prometheus/latest/querying/api/#querying-label-values
export type LabelValuesResult = string[];

View file

@ -23,6 +23,8 @@ export interface RangeSamples {
export type SampleValue = [number, string];
export type SampleHistogram = [number, Histogram];
// Result type for /api/v1/query endpoint.
// See: https://prometheus.io/docs/prometheus/latest/querying/api/#instant-queries
export type InstantQueryResult =
| {
resultType: "vector";

View file

@ -50,10 +50,14 @@ type AlertingRuleGroup = Omit<RuleGroup, "rules"> & {
rules: AlertingRule[];
};
export interface RulesMap {
// Result type for /api/v1/alerts endpoint.
// See: https://prometheus.io/docs/prometheus/latest/querying/api/#alerts
export interface RulesResult {
groups: RuleGroup[];
}
export interface AlertingRulesMap {
// Same as RulesResult above, but can be used when the caller ensures via a
// "type=alert" query parameter that all rules are alerting rules.
export interface AlertingRulesResult {
groups: AlertingRuleGroup[];
}

View file

@ -1 +1,2 @@
// Result type for /api/v1/scrape_pools endpoint.
export type ScrapePoolsResult = { scrapePools: string[] };

View file

@ -20,6 +20,8 @@ export interface DroppedTarget {
discoveredLabels: Labels;
}
// Result type for /api/v1/targets endpoint.
// See: https://prometheus.io/docs/prometheus/latest/querying/api/#targets
export type TargetsResult = {
activeTargets: Target[];
droppedTargets: DroppedTarget[];

View file

@ -11,7 +11,9 @@ interface HeadStats {
maxTime: number;
}
export interface TSDBMap {
// Result type for /api/v1/status/tsdb endpoint.
// See: https://prometheus.io/docs/prometheus/latest/querying/api/#tsdb-stats
export interface TSDBStatusResult {
headStats: HeadStats;
seriesCountByMetricName: Stats[];
labelValueCountByLabelName: Stats[];

View file

@ -1,7 +1,7 @@
import { Badge, BadgeVariant, Group, MantineColor } from "@mantine/core";
import { FC } from "react";
import { escapeString } from "./lib/escapeString";
import badgeClasses from "./Badge.module.css";
import { escapeString } from "../lib/escapeString";
import badgeClasses from "../Badge.module.css";
export interface LabelBadgesProps {
labels: Record<string, string>;

View file

@ -1,9 +1,9 @@
import { Badge, Box, Card, Group, useComputedColorScheme } from "@mantine/core";
import { IconClockPause, IconClockPlay } from "@tabler/icons-react";
import { FC } from "react";
import { formatPrometheusDuration } from "./lib/formatTime";
import codeboxClasses from "./codebox.module.css";
import { Rule } from "./api/responseTypes/rules";
import { formatPrometheusDuration } from "../lib/formatTime";
import codeboxClasses from "./RuleDefinition.module.css";
import { Rule } from "../api/responseTypes/rules";
import CodeMirror, { EditorView } from "@uiw/react-codemirror";
import { syntaxHighlighting } from "@codemirror/language";
import {
@ -11,7 +11,7 @@ import {
darkPromqlHighlighter,
lightTheme,
promqlHighlighter,
} from "./codemirror/theme";
} from "../codemirror/theme";
import { PromQLExtension } from "@prometheus-io/codemirror-promql";
import { LabelBadges } from "./LabelBadges";

View file

@ -1,8 +1,8 @@
import { Popover, ActionIcon, Fieldset, Checkbox, Stack } from "@mantine/core";
import { IconSettings } from "@tabler/icons-react";
import { FC } from "react";
import { useAppDispatch, useAppSelector } from "./state/hooks";
import { updateSettings } from "./state/settingsSlice";
import { useAppDispatch, useAppSelector } from "../state/hooks";
import { updateSettings } from "../state/settingsSlice";
const SettingsMenu: FC = () => {
const {

View file

@ -1,3 +1,4 @@
// Used for escaping escape sequences and double quotes in double-quoted strings.
export const escapeString = (str: string) => {
return str.replace(/([\\"])/g, "\\$1");
};

View file

@ -4,6 +4,7 @@ dayjs.extend(duration);
import utc from "dayjs/plugin/utc";
dayjs.extend(utc);
// Parse Prometheus-specific duration strings such as "5m" or "1d2h3m4s" into milliseconds.
export const parsePrometheusDuration = (durationStr: string): number | null => {
if (durationStr === "") {
return null;
@ -44,6 +45,7 @@ export const parsePrometheusDuration = (durationStr: string): number | null => {
return dur;
};
// Format a duration in milliseconds into a Prometheus duration string like "1d2h3m4s".
export const formatPrometheusDuration = (d: number): string => {
let ms = d;
let r = "";

View file

@ -12,19 +12,19 @@ import {
Alert,
} from "@mantine/core";
import { useSuspenseAPIQuery } from "../api/api";
import { AlertingRulesMap } from "../api/responseTypes/rules";
import { AlertingRulesResult } from "../api/responseTypes/rules";
import badgeClasses from "../Badge.module.css";
import RuleDefinition from "../RuleDefinition";
import RuleDefinition from "../components/RuleDefinition";
import { humanizeDurationRelative, now } from "../lib/formatTime";
import { Fragment } from "react";
import { StateMultiSelect } from "../StateMultiSelect";
import { StateMultiSelect } from "../components/StateMultiSelect";
import { useAppDispatch, useAppSelector } from "../state/hooks";
import { IconInfoCircle, IconSearch } from "@tabler/icons-react";
import { LabelBadges } from "../LabelBadges";
import { LabelBadges } from "../components/LabelBadges";
import { updateAlertFilters } from "../state/alertsPageSlice";
export default function AlertsPage() {
const { data } = useSuspenseAPIQuery<AlertingRulesMap>({
const { data } = useSuspenseAPIQuery<AlertingRulesResult>({
path: `/rules`,
params: {
type: "alert",

View file

@ -24,9 +24,9 @@ import {
IconRepeat,
} from "@tabler/icons-react";
import { useSuspenseAPIQuery } from "../api/api";
import { RulesMap } from "../api/responseTypes/rules";
import { RulesResult } from "../api/responseTypes/rules";
import badgeClasses from "../Badge.module.css";
import RuleDefinition from "../RuleDefinition";
import RuleDefinition from "../components/RuleDefinition";
const healthBadgeClass = (state: string) => {
switch (state) {
@ -42,7 +42,7 @@ const healthBadgeClass = (state: string) => {
};
export default function RulesPage() {
const { data } = useSuspenseAPIQuery<RulesMap>({ path: `/rules` });
const { data } = useSuspenseAPIQuery<RulesResult>({ path: `/rules` });
return (
<Stack mt="xs">

View file

@ -1,6 +1,6 @@
import { Stack, Card, Group, Table, Text } from "@mantine/core";
import { useSuspenseAPIQuery } from "../api/api";
import { TSDBMap } from "../api/responseTypes/tsdbStatus";
import { TSDBStatusResult } from "../api/responseTypes/tsdbStatus";
import { useAppSelector } from "../state/hooks";
import { formatTimestamp } from "../lib/formatTime";
@ -15,7 +15,7 @@ export default function TSDBStatusPage() {
seriesCountByLabelValuePair,
},
},
} = useSuspenseAPIQuery<TSDBMap>({ path: `/status/tsdb` });
} = useSuspenseAPIQuery<TSDBStatusResult>({ path: `/status/tsdb` });
const useLocalTime = useAppSelector((state) => state.settings.useLocalTime);

View file

@ -18,7 +18,7 @@ import {
IconLayoutNavbarExpand,
IconSearch,
} from "@tabler/icons-react";
import { StateMultiSelect } from "../StateMultiSelect";
import { StateMultiSelect } from "../components/StateMultiSelect";
import { useSuspenseAPIQuery } from "../api/api";
import { ScrapePoolsResult } from "../api/responseTypes/scrapePools";
import { Target, TargetsResult } from "../api/responseTypes/targets";
@ -29,14 +29,14 @@ import {
humanizeDuration,
now,
} from "../lib/formatTime";
import { LabelBadges } from "../LabelBadges";
import { LabelBadges } from "../components/LabelBadges";
import { useAppDispatch, useAppSelector } from "../state/hooks";
import {
setCollapsedPools,
updateTargetFilters,
} from "../state/targetsPageSlice";
import EndpointLink from "../EndpointLink";
import CustomInfiniteScroll from "../CustomInfiniteScroll";
import EndpointLink from "../components/EndpointLink";
import CustomInfiniteScroll from "../components/CustomInfiniteScroll";
type ScrapePool = {
targets: Target[];

View file

@ -1,6 +1,6 @@
import { useDispatch, useSelector } from "react-redux";
import type { RootState, AppDispatch } from "./store";
// Use throughout your app instead of plain `useDispatch` and `useSelector`
// Use these typed hooks throughout the app instead of plain `useDispatch` and `useSelector`
export const useAppDispatch = useDispatch.withTypes<AppDispatch>();
export const useAppSelector = useSelector.withTypes<RootState>();