mirror of
https://github.com/prometheus/prometheus.git
synced 2024-09-19 23:37:31 -07:00
WIP
Signed-off-by: Julius Volz <julius.volz@gmail.com>
This commit is contained in:
parent
5aa3d8260a
commit
2c7bc9833a
|
@ -322,9 +322,9 @@ function App() {
|
|||
color="gray"
|
||||
title="Documentation"
|
||||
aria-label="Documentation"
|
||||
size={32}
|
||||
size={rem(32)}
|
||||
>
|
||||
<IconBook size={20} />
|
||||
<IconBook style={{ width: "70%", height: "70%" }} />
|
||||
</ActionIcon>
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Alert } from "@mantine/core";
|
||||
import { Alert, rem } from "@mantine/core";
|
||||
import { IconAlertTriangle } from "@tabler/icons-react";
|
||||
import { Component, ErrorInfo, ReactNode } from "react";
|
||||
import { useLocation } from "react-router-dom";
|
||||
|
@ -32,7 +32,7 @@ class ErrorBoundary extends Component<Props, State> {
|
|||
<Alert
|
||||
color="red"
|
||||
title={this.props.title || "Error querying page data"}
|
||||
icon={<IconAlertTriangle size={14} />}
|
||||
icon={<IconAlertTriangle size={rem(14)} />}
|
||||
maw={500}
|
||||
mx="auto"
|
||||
mt="lg"
|
||||
|
|
31
web/ui/mantine-ui/src/components/InfoPageCard.tsx
Normal file
31
web/ui/mantine-ui/src/components/InfoPageCard.tsx
Normal file
|
@ -0,0 +1,31 @@
|
|||
import { Card, em, Group } from "@mantine/core";
|
||||
import { TablerIconsProps } from "@tabler/icons-react";
|
||||
import { FC, ReactNode } from "react";
|
||||
|
||||
const InfoPageCard: FC<{
|
||||
children: ReactNode;
|
||||
title?: string;
|
||||
icon?: React.ComponentType<TablerIconsProps>;
|
||||
}> = ({ children, title, icon: Icon }) => {
|
||||
return (
|
||||
<Card shadow="xs" withBorder p="md">
|
||||
{title && (
|
||||
<Group
|
||||
wrap="nowrap"
|
||||
align="center"
|
||||
ml="xs"
|
||||
mb="sm"
|
||||
gap="xs"
|
||||
fz="xl"
|
||||
fw={600}
|
||||
>
|
||||
{Icon && <Icon style={{ width: em(17.5), height: em(17.5) }} />}
|
||||
{title}
|
||||
</Group>
|
||||
)}
|
||||
{children}
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
export default InfoPageCard;
|
12
web/ui/mantine-ui/src/components/InfoPageStack.tsx
Normal file
12
web/ui/mantine-ui/src/components/InfoPageStack.tsx
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { Stack } from "@mantine/core";
|
||||
import { FC, ReactNode } from "react";
|
||||
|
||||
const InfoPageStack: FC<{ children: ReactNode }> = ({ children }) => {
|
||||
return (
|
||||
<Stack gap="lg" maw={1000} mx="auto" mt="xs">
|
||||
{children}
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
export default InfoPageStack;
|
|
@ -1,4 +1,11 @@
|
|||
import { Popover, ActionIcon, Fieldset, Checkbox, Stack } from "@mantine/core";
|
||||
import {
|
||||
Popover,
|
||||
ActionIcon,
|
||||
Fieldset,
|
||||
Checkbox,
|
||||
Stack,
|
||||
Slider,
|
||||
} from "@mantine/core";
|
||||
import { IconSettings } from "@tabler/icons-react";
|
||||
import { FC } from "react";
|
||||
import { useAppDispatch } from "../state/hooks";
|
||||
|
@ -24,7 +31,7 @@ const SettingsMenu: FC = () => {
|
|||
aria-label="Settings"
|
||||
size={32}
|
||||
>
|
||||
<IconSettings size={20} />
|
||||
<IconSettings style={{ width: "70%", height: "70%" }} />
|
||||
</ActionIcon>
|
||||
</Popover.Target>
|
||||
<Popover.Dropdown>
|
||||
|
@ -39,6 +46,14 @@ const SettingsMenu: FC = () => {
|
|||
)
|
||||
}
|
||||
/>
|
||||
<Slider
|
||||
defaultValue={100}
|
||||
min={70}
|
||||
max={130}
|
||||
onChange={(value) => {
|
||||
document.documentElement.style.fontSize = `${value}%`;
|
||||
}}
|
||||
/>
|
||||
</Fieldset>
|
||||
|
||||
<Fieldset p="md" legend="Query page settings">
|
||||
|
|
35
web/ui/mantine-ui/src/mantine-overrides.css
Normal file
35
web/ui/mantine-ui/src/mantine-overrides.css
Normal file
|
@ -0,0 +1,35 @@
|
|||
.promql-code {
|
||||
font-family: "DejaVu Sans Mono", monospace;
|
||||
}
|
||||
|
||||
.promql-keyword {
|
||||
color: light-dark(#008080, #14bfad);
|
||||
}
|
||||
|
||||
.promql-metric-name {
|
||||
/* Should already inherit the right color from the theme. */
|
||||
}
|
||||
|
||||
.promql-label-name {
|
||||
color: light-dark(#800000, #ff8585);
|
||||
}
|
||||
|
||||
.promql-string {
|
||||
color: light-dark(#a31515, #fca5a5);
|
||||
}
|
||||
|
||||
.promql-paren,
|
||||
.promql-brace {
|
||||
}
|
||||
|
||||
.promql-ellipsis {
|
||||
color: light-dark(rgb(170, 170, 170), rgb(170, 170, 170));
|
||||
}
|
||||
|
||||
.promql-duration {
|
||||
color: light-dark(#09885a, #22c55e);
|
||||
}
|
||||
|
||||
.promql-number {
|
||||
color: light-dark(#09885a, #22c55e);
|
||||
}
|
|
@ -1,9 +1,11 @@
|
|||
import { Alert, Card, Group, Stack, Table, Text } from "@mantine/core";
|
||||
import { Alert, Table } from "@mantine/core";
|
||||
import { IconBell, IconBellOff, IconInfoCircle } from "@tabler/icons-react";
|
||||
|
||||
import { useSuspenseAPIQuery } from "../api/api";
|
||||
import { AlertmanagersResult } from "../api/responseTypes/alertmanagers";
|
||||
import EndpointLink from "../components/EndpointLink";
|
||||
import InfoPageCard from "../components/InfoPageCard";
|
||||
import InfoPageStack from "../components/InfoPageStack";
|
||||
|
||||
export const targetPoolDisplayLimit = 20;
|
||||
|
||||
|
@ -18,14 +20,8 @@ export default function AlertmanagerDiscoveryPage() {
|
|||
});
|
||||
|
||||
return (
|
||||
<Stack gap="lg" maw={1000} mx="auto" mt="xs">
|
||||
<Card shadow="xs" withBorder p="md">
|
||||
<Group wrap="nowrap" align="center" ml="xs" mb="sm" gap="xs">
|
||||
<IconBell size={22} />
|
||||
<Text fz="xl" fw={600}>
|
||||
Active Alertmanagers
|
||||
</Text>
|
||||
</Group>
|
||||
<InfoPageStack>
|
||||
<InfoPageCard title="Active Alertmanagers" icon={IconBell}>
|
||||
{activeAlertmanagers.length === 0 ? (
|
||||
<Alert title="No active alertmanagers" icon={<IconInfoCircle />}>
|
||||
No active alertmanagers found.
|
||||
|
@ -46,14 +42,8 @@ export default function AlertmanagerDiscoveryPage() {
|
|||
</Table.Tbody>
|
||||
</Table>
|
||||
)}
|
||||
</Card>
|
||||
<Card shadow="xs" withBorder p="md">
|
||||
<Group wrap="nowrap" align="center" ml="xs" mb="sm" gap="xs">
|
||||
<IconBellOff size={22} />
|
||||
<Text fz="xl" fw={600}>
|
||||
Dropped Alertmanagers
|
||||
</Text>
|
||||
</Group>
|
||||
</InfoPageCard>
|
||||
<InfoPageCard title="Dropped Alertmanagers" icon={IconBellOff}>
|
||||
{droppedAlertmanagers.length === 0 ? (
|
||||
<Alert title="No dropped alertmanagers" icon={<IconInfoCircle />}>
|
||||
No dropped alertmanagers found.
|
||||
|
@ -74,7 +64,7 @@ export default function AlertmanagerDiscoveryPage() {
|
|||
</Table.Tbody>
|
||||
</Table>
|
||||
)}
|
||||
</Card>
|
||||
</Stack>
|
||||
</InfoPageCard>
|
||||
</InfoPageStack>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ import {
|
|||
TextInput,
|
||||
rem,
|
||||
keys,
|
||||
Card,
|
||||
} from "@mantine/core";
|
||||
import {
|
||||
IconSelector,
|
||||
|
@ -18,6 +17,8 @@ import {
|
|||
} from "@tabler/icons-react";
|
||||
import classes from "./FlagsPage.module.css";
|
||||
import { useSuspenseAPIQuery } from "../api/api";
|
||||
import InfoPageStack from "../components/InfoPageStack";
|
||||
import InfoPageCard from "../components/InfoPageCard";
|
||||
|
||||
interface RowData {
|
||||
flag: string;
|
||||
|
@ -124,59 +125,61 @@ export default function FlagsPage() {
|
|||
));
|
||||
|
||||
return (
|
||||
<Card shadow="xs" maw={1000} mx="auto" mt="xs" withBorder>
|
||||
<TextInput
|
||||
placeholder="Filter by flag name or value"
|
||||
mb="md"
|
||||
autoFocus
|
||||
leftSection={
|
||||
<IconSearch
|
||||
style={{ width: rem(16), height: rem(16) }}
|
||||
stroke={1.5}
|
||||
/>
|
||||
}
|
||||
value={search}
|
||||
onChange={handleSearchChange}
|
||||
/>
|
||||
<Table
|
||||
horizontalSpacing="md"
|
||||
verticalSpacing="xs"
|
||||
miw={700}
|
||||
layout="fixed"
|
||||
>
|
||||
<Table.Tbody>
|
||||
<Table.Tr>
|
||||
<Th
|
||||
sorted={sortBy === "flag"}
|
||||
reversed={reverseSortDirection}
|
||||
onSort={() => setSorting("flag")}
|
||||
>
|
||||
Flag
|
||||
</Th>
|
||||
|
||||
<Th
|
||||
sorted={sortBy === "value"}
|
||||
reversed={reverseSortDirection}
|
||||
onSort={() => setSorting("value")}
|
||||
>
|
||||
Value
|
||||
</Th>
|
||||
</Table.Tr>
|
||||
</Table.Tbody>
|
||||
<Table.Tbody>
|
||||
{rows.length > 0 ? (
|
||||
rows
|
||||
) : (
|
||||
<InfoPageStack>
|
||||
<InfoPageCard>
|
||||
<TextInput
|
||||
placeholder="Filter by flag name or value"
|
||||
mb="md"
|
||||
autoFocus
|
||||
leftSection={
|
||||
<IconSearch
|
||||
style={{ width: rem(16), height: rem(16) }}
|
||||
stroke={1.5}
|
||||
/>
|
||||
}
|
||||
value={search}
|
||||
onChange={handleSearchChange}
|
||||
/>
|
||||
<Table
|
||||
horizontalSpacing="md"
|
||||
verticalSpacing="xs"
|
||||
miw={700}
|
||||
layout="fixed"
|
||||
>
|
||||
<Table.Tbody>
|
||||
<Table.Tr>
|
||||
<Table.Td colSpan={2}>
|
||||
<Text fw={500} ta="center">
|
||||
Nothing found
|
||||
</Text>
|
||||
</Table.Td>
|
||||
<Th
|
||||
sorted={sortBy === "flag"}
|
||||
reversed={reverseSortDirection}
|
||||
onSort={() => setSorting("flag")}
|
||||
>
|
||||
Flag
|
||||
</Th>
|
||||
|
||||
<Th
|
||||
sorted={sortBy === "value"}
|
||||
reversed={reverseSortDirection}
|
||||
onSort={() => setSorting("value")}
|
||||
>
|
||||
Value
|
||||
</Th>
|
||||
</Table.Tr>
|
||||
)}
|
||||
</Table.Tbody>
|
||||
</Table>
|
||||
</Card>
|
||||
</Table.Tbody>
|
||||
<Table.Tbody>
|
||||
{rows.length > 0 ? (
|
||||
rows
|
||||
) : (
|
||||
<Table.Tr>
|
||||
<Table.Td colSpan={2}>
|
||||
<Text fw={500} ta="center">
|
||||
Nothing found
|
||||
</Text>
|
||||
</Table.Td>
|
||||
</Table.Tr>
|
||||
)}
|
||||
</Table.Tbody>
|
||||
</Table>
|
||||
</InfoPageCard>
|
||||
</InfoPageStack>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import { Card, Group, Stack, Table, Text } from "@mantine/core";
|
||||
import { Table } from "@mantine/core";
|
||||
import { useSuspenseAPIQuery } from "../api/api";
|
||||
import { IconRun, IconWall } from "@tabler/icons-react";
|
||||
import { formatTimestamp } from "../lib/formatTime";
|
||||
import { useSettings } from "../state/settingsSlice";
|
||||
import InfoPageCard from "../components/InfoPageCard";
|
||||
import InfoPageStack from "../components/InfoPageStack";
|
||||
|
||||
export default function StatusPage() {
|
||||
const { data: buildinfo } = useSuspenseAPIQuery<Record<string, string>>({
|
||||
|
@ -42,14 +44,8 @@ export default function StatusPage() {
|
|||
};
|
||||
|
||||
return (
|
||||
<Stack gap="lg" maw={1000} mx="auto" mt="xs">
|
||||
<Card shadow="xs" withBorder p="md">
|
||||
<Group wrap="nowrap" align="center" ml="xs" mb="sm" gap="xs">
|
||||
<IconWall size={22} />
|
||||
<Text fz="xl" fw={600}>
|
||||
Build information
|
||||
</Text>
|
||||
</Group>
|
||||
<InfoPageStack>
|
||||
<InfoPageCard title="Build information" icon={IconWall}>
|
||||
<Table layout="fixed">
|
||||
<Table.Tbody>
|
||||
{Object.entries(buildinfo.data).map(([k, v]) => (
|
||||
|
@ -60,14 +56,8 @@ export default function StatusPage() {
|
|||
))}
|
||||
</Table.Tbody>
|
||||
</Table>
|
||||
</Card>
|
||||
<Card shadow="xs" withBorder p="md">
|
||||
<Group wrap="nowrap" align="center" ml="xs" mb="sm" gap="xs">
|
||||
<IconRun size={22} />
|
||||
<Text fz="xl" fw={600}>
|
||||
Runtime information
|
||||
</Text>
|
||||
</Group>
|
||||
</InfoPageCard>
|
||||
<InfoPageCard title="Runtime information" icon={IconRun}>
|
||||
<Table layout="fixed">
|
||||
<Table.Tbody>
|
||||
{Object.entries(runtimeinfo.data).map(([k, v]) => {
|
||||
|
@ -84,7 +74,7 @@ export default function StatusPage() {
|
|||
})}
|
||||
</Table.Tbody>
|
||||
</Table>
|
||||
</Card>
|
||||
</Stack>
|
||||
</InfoPageCard>
|
||||
</InfoPageStack>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import { Stack, Card, Table, Text } from "@mantine/core";
|
||||
import { Table } from "@mantine/core";
|
||||
import { useSuspenseAPIQuery } from "../api/api";
|
||||
import { TSDBStatusResult } from "../api/responseTypes/tsdbStatus";
|
||||
import { formatTimestamp } from "../lib/formatTime";
|
||||
import { useSettings } from "../state/settingsSlice";
|
||||
import InfoPageStack from "../components/InfoPageStack";
|
||||
import InfoPageCard from "../components/InfoPageCard";
|
||||
|
||||
export default function TSDBStatusPage() {
|
||||
const {
|
||||
|
@ -41,7 +43,7 @@ export default function TSDBStatusPage() {
|
|||
];
|
||||
|
||||
return (
|
||||
<Stack gap="lg" maw={1000} mx="auto" mt="xs">
|
||||
<InfoPageStack>
|
||||
{[
|
||||
{
|
||||
title: "TSDB Head Status",
|
||||
|
@ -70,10 +72,7 @@ export default function TSDBStatusPage() {
|
|||
formatAsCode: true,
|
||||
},
|
||||
].map(({ title, unit = "Count", stats, formatAsCode }) => (
|
||||
<Card shadow="xs" withBorder p="md">
|
||||
<Text fz="xl" fw={600} ml="xs" mb="sm">
|
||||
{title}
|
||||
</Text>
|
||||
<InfoPageCard title={title}>
|
||||
<Table layout="fixed">
|
||||
<Table.Thead>
|
||||
<Table.Tr>
|
||||
|
@ -82,24 +81,22 @@ export default function TSDBStatusPage() {
|
|||
</Table.Tr>
|
||||
</Table.Thead>
|
||||
<Table.Tbody>
|
||||
{stats.map(({ name, value }) => {
|
||||
return (
|
||||
<Table.Tr key={name}>
|
||||
<Table.Td
|
||||
style={{
|
||||
wordBreak: "break-all",
|
||||
}}
|
||||
>
|
||||
{formatAsCode ? <code>{name}</code> : name}
|
||||
</Table.Td>
|
||||
<Table.Td>{value}</Table.Td>
|
||||
</Table.Tr>
|
||||
);
|
||||
})}
|
||||
{stats.map(({ name, value }) => (
|
||||
<Table.Tr key={name}>
|
||||
<Table.Td
|
||||
style={{
|
||||
wordBreak: "break-all",
|
||||
}}
|
||||
>
|
||||
{formatAsCode ? <code>{name}</code> : name}
|
||||
</Table.Td>
|
||||
<Table.Td>{value}</Table.Td>
|
||||
</Table.Tr>
|
||||
))}
|
||||
</Table.Tbody>
|
||||
</Table>
|
||||
</Card>
|
||||
</InfoPageCard>
|
||||
))}
|
||||
</Stack>
|
||||
</InfoPageStack>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -6,11 +6,19 @@ export default defineConfig({
|
|||
plugins: [react()],
|
||||
server: {
|
||||
proxy: {
|
||||
// "/api": {
|
||||
// target: "http://localhost:9090",
|
||||
// },
|
||||
// "/-/": {
|
||||
// target: "http://localhost:9090",
|
||||
// },
|
||||
"/api": {
|
||||
target: "http://localhost:9090",
|
||||
target: "https://demo-new.promlabs.com/",
|
||||
changeOrigin: true,
|
||||
},
|
||||
"/-/": {
|
||||
target: "http://localhost:9090",
|
||||
target: "https://demo-new.promlabs.com/",
|
||||
changeOrigin: true,
|
||||
},
|
||||
// "/api": {
|
||||
// target: "https://prometheus.demo.do.prometheus.io/",
|
||||
|
|
Loading…
Reference in a new issue