diff --git a/web/ui/mantine-ui/src/App.tsx b/web/ui/mantine-ui/src/App.tsx index f677dd880..aa5eb3714 100644 --- a/web/ui/mantine-ui/src/App.tsx +++ b/web/ui/mantine-ui/src/App.tsx @@ -2,6 +2,7 @@ import "@mantine/core/styles.css"; import "@mantine/code-highlight/styles.css"; import "@mantine/notifications/styles.css"; import "@mantine/dates/styles.css"; +import "./mantine-overrides.css"; import classes from "./App.module.css"; import PrometheusLogo from "./images/prometheus-logo.svg"; @@ -67,11 +68,10 @@ import { QueryParamProvider } from "use-query-params"; import { ReactRouter6Adapter } from "use-query-params/adapters/react-router-6"; import ServiceDiscoveryPage from "./pages/service-discovery/ServiceDiscoveryPage"; import AlertmanagerDiscoveryPage from "./pages/AlertmanagerDiscoveryPage"; +import { actionIconStyle, navIconStyle } from "./styles"; const queryClient = new QueryClient(); -const navIconStyle = { width: rem(16), height: rem(16) }; - const mainNavPages = [ { title: "Query", @@ -322,9 +322,9 @@ function App() { color="gray" title="Documentation" aria-label="Documentation" - size={32} + size={rem(32)} > - + ); diff --git a/web/ui/mantine-ui/src/components/ErrorBoundary.tsx b/web/ui/mantine-ui/src/components/ErrorBoundary.tsx index 3416623d3..6e7e4c0cb 100644 --- a/web/ui/mantine-ui/src/components/ErrorBoundary.tsx +++ b/web/ui/mantine-ui/src/components/ErrorBoundary.tsx @@ -32,7 +32,7 @@ class ErrorBoundary extends Component { } + icon={} maw={500} mx="auto" mt="lg" diff --git a/web/ui/mantine-ui/src/components/InfoPageCard.tsx b/web/ui/mantine-ui/src/components/InfoPageCard.tsx new file mode 100644 index 000000000..3d0817e6d --- /dev/null +++ b/web/ui/mantine-ui/src/components/InfoPageCard.tsx @@ -0,0 +1,32 @@ +import { Card, Group } from "@mantine/core"; +import { TablerIconsProps } from "@tabler/icons-react"; +import { FC, ReactNode } from "react"; +import { infoPageCardTitleIconStyle } from "../styles"; + +const InfoPageCard: FC<{ + children: ReactNode; + title?: string; + icon?: React.ComponentType; +}> = ({ children, title, icon: Icon }) => { + return ( + + {title && ( + + {Icon && } + {title} + + )} + {children} + + ); +}; + +export default InfoPageCard; diff --git a/web/ui/mantine-ui/src/components/InfoPageStack.tsx b/web/ui/mantine-ui/src/components/InfoPageStack.tsx new file mode 100644 index 000000000..eacc4f831 --- /dev/null +++ b/web/ui/mantine-ui/src/components/InfoPageStack.tsx @@ -0,0 +1,12 @@ +import { Stack } from "@mantine/core"; +import { FC, ReactNode } from "react"; + +const InfoPageStack: FC<{ children: ReactNode }> = ({ children }) => { + return ( + + {children} + + ); +}; + +export default InfoPageStack; diff --git a/web/ui/mantine-ui/src/components/RuleDefinition.tsx b/web/ui/mantine-ui/src/components/RuleDefinition.tsx index 10944f6e7..f3c4c8848 100644 --- a/web/ui/mantine-ui/src/components/RuleDefinition.tsx +++ b/web/ui/mantine-ui/src/components/RuleDefinition.tsx @@ -4,7 +4,6 @@ import { Box, Card, Group, - rem, Table, Tooltip, useComputedColorScheme, @@ -25,6 +24,7 @@ import { import { PromQLExtension } from "@prometheus-io/codemirror-promql"; import { LabelBadges } from "./LabelBadges"; import { useSettings } from "../state/settingsSlice"; +import { actionIconStyle, badgeIconStyle } from "../styles"; const promqlExtension = new PromQLExtension(); @@ -64,7 +64,7 @@ const RuleDefinition: FC<{ rule: Rule }> = ({ rule }) => { }} className={codeboxClasses.queryButton} > - + @@ -74,7 +74,7 @@ const RuleDefinition: FC<{ rule: Rule }> = ({ rule }) => { } + leftSection={} > for: {formatPrometheusDuration(rule.duration * 1000)} @@ -83,7 +83,7 @@ const RuleDefinition: FC<{ rule: Rule }> = ({ rule }) => { } + leftSection={} > keep_firing_for: {formatPrometheusDuration(rule.duration * 1000)} diff --git a/web/ui/mantine-ui/src/components/SettingsMenu.tsx b/web/ui/mantine-ui/src/components/SettingsMenu.tsx index c0631b1b4..ada252d57 100644 --- a/web/ui/mantine-ui/src/components/SettingsMenu.tsx +++ b/web/ui/mantine-ui/src/components/SettingsMenu.tsx @@ -3,6 +3,7 @@ import { IconSettings } from "@tabler/icons-react"; import { FC } from "react"; import { useAppDispatch } from "../state/hooks"; import { updateSettings, useSettings } from "../state/settingsSlice"; +import { actionIconStyle } from "../styles"; const SettingsMenu: FC = () => { const { @@ -24,7 +25,7 @@ const SettingsMenu: FC = () => { aria-label="Settings" size={32} > - + diff --git a/web/ui/mantine-ui/src/components/StateMultiSelect.tsx b/web/ui/mantine-ui/src/components/StateMultiSelect.tsx index b986d7aa5..4621c5b9e 100644 --- a/web/ui/mantine-ui/src/components/StateMultiSelect.tsx +++ b/web/ui/mantine-ui/src/components/StateMultiSelect.tsx @@ -10,6 +10,7 @@ import { useCombobox, } from "@mantine/core"; import { IconHeartRateMonitor } from "@tabler/icons-react"; +import { inputIconStyle } from "../styles"; interface StatePillProps extends React.ComponentPropsWithoutRef<"div"> { value: string; @@ -80,7 +81,7 @@ export const StateMultiSelect: FC = ({ pointer onClick={() => combobox.toggleDropdown()} miw={200} - leftSection={} + leftSection={} rightSection={ values.length > 0 ? ( onChange([])} /> diff --git a/web/ui/mantine-ui/src/mantine-overrides.css b/web/ui/mantine-ui/src/mantine-overrides.css new file mode 100644 index 000000000..b9662f8d5 --- /dev/null +++ b/web/ui/mantine-ui/src/mantine-overrides.css @@ -0,0 +1,4 @@ +.mantine-Badge-label { + overflow: unset; + text-overflow: unset; +} diff --git a/web/ui/mantine-ui/src/pages/AgentPage.tsx b/web/ui/mantine-ui/src/pages/AgentPage.tsx index 34c0a6708..d11af4958 100644 --- a/web/ui/mantine-ui/src/pages/AgentPage.tsx +++ b/web/ui/mantine-ui/src/pages/AgentPage.tsx @@ -1,16 +1,16 @@ -import { Card, Group, Text } from "@mantine/core"; +import { Text } from "@mantine/core"; import { IconSpy } from "@tabler/icons-react"; import { FC } from "react"; +import InfoPageStack from "../components/InfoPageStack"; +import InfoPageCard from "../components/InfoPageCard"; const AgentPage: FC = () => { return ( - - - - - Prometheus Agent - - + + This Prometheus instance is running in agent mode. In this mode, Prometheus is only used to scrape discovered targets and @@ -18,9 +18,10 @@ const AgentPage: FC = () => { Some features are not available in this mode, such as querying and - alerting. - - + alerting. + + + ); }; diff --git a/web/ui/mantine-ui/src/pages/AlertmanagerDiscoveryPage.tsx b/web/ui/mantine-ui/src/pages/AlertmanagerDiscoveryPage.tsx index 2ea248117..d1ffb2f5f 100644 --- a/web/ui/mantine-ui/src/pages/AlertmanagerDiscoveryPage.tsx +++ b/web/ui/mantine-ui/src/pages/AlertmanagerDiscoveryPage.tsx @@ -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 ( - - - - - - Active Alertmanagers - - + + {activeAlertmanagers.length === 0 ? ( }> No active alertmanagers found. @@ -46,14 +42,8 @@ export default function AlertmanagerDiscoveryPage() { )} - - - - - - Dropped Alertmanagers - - + + {droppedAlertmanagers.length === 0 ? ( }> No dropped alertmanagers found. @@ -74,7 +64,7 @@ export default function AlertmanagerDiscoveryPage() { )} - - + + ); } diff --git a/web/ui/mantine-ui/src/pages/AlertsPage.tsx b/web/ui/mantine-ui/src/pages/AlertsPage.tsx index 852236f86..1513f73d5 100644 --- a/web/ui/mantine-ui/src/pages/AlertsPage.tsx +++ b/web/ui/mantine-ui/src/pages/AlertsPage.tsx @@ -32,6 +32,7 @@ import { } from "use-query-params"; import { useDebouncedValue } from "@mantine/hooks"; import { KVSearch } from "@nexucis/kvsearch"; +import { inputIconStyle } from "../styles"; type AlertsPageData = { // How many rules are in each state across all groups. @@ -190,7 +191,7 @@ export default function AlertsPage() { /> } + leftSection={} placeholder="Filter by rule name or labels" value={searchFilter || ""} onChange={(event) => @@ -199,7 +200,7 @@ export default function AlertsPage() { > {alertsPageData.groups.length === 0 ? ( - }> + }> No rules found. ) : ( @@ -207,7 +208,7 @@ export default function AlertsPage() { alertsPageData.groups.length !== shownGroups.length && ( } + icon={} > Hiding {alertsPageData.groups.length - shownGroups.length} empty groups due to filters or no rules. @@ -326,7 +327,7 @@ export default function AlertsPage() { {r.rule.alerts.length > 0 && ( - + Alert labels State Active Since diff --git a/web/ui/mantine-ui/src/pages/FlagsPage.tsx b/web/ui/mantine-ui/src/pages/FlagsPage.tsx index d90328f96..856ab9a40 100644 --- a/web/ui/mantine-ui/src/pages/FlagsPage.tsx +++ b/web/ui/mantine-ui/src/pages/FlagsPage.tsx @@ -8,7 +8,6 @@ import { TextInput, rem, keys, - Card, } from "@mantine/core"; import { IconSelector, @@ -18,6 +17,9 @@ 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"; +import { inputIconStyle } from "../styles"; interface RowData { flag: string; @@ -124,59 +126,56 @@ export default function FlagsPage() { )); return ( - - - } - value={search} - onChange={handleSearchChange} - /> -
- - - - - - - - - {rows.length > 0 ? ( - rows - ) : ( + + + } + value={search} + onChange={handleSearchChange} + /> +
setSorting("flag")} - > - Flag - setSorting("value")} - > - Value -
+ - - - Nothing found - - + + + - )} - -
setSorting("flag")} + > + Flag + setSorting("value")} + > + Value +
- + + + {rows.length > 0 ? ( + rows + ) : ( + + + + Nothing found + + + + )} + + + + ); } diff --git a/web/ui/mantine-ui/src/pages/RulesPage.tsx b/web/ui/mantine-ui/src/pages/RulesPage.tsx index a335228f3..ce0097776 100644 --- a/web/ui/mantine-ui/src/pages/RulesPage.tsx +++ b/web/ui/mantine-ui/src/pages/RulesPage.tsx @@ -27,6 +27,7 @@ import { useSuspenseAPIQuery } from "../api/api"; import { RulesResult } from "../api/responseTypes/rules"; import badgeClasses from "../Badge.module.css"; import RuleDefinition from "../components/RuleDefinition"; +import { badgeIconStyle } from "../styles"; const healthBadgeClass = (state: string) => { switch (state) { @@ -47,7 +48,7 @@ export default function RulesPage() { return ( {data.data.groups.length === 0 && ( - }> + }> No rule groups configured. )} @@ -74,7 +75,7 @@ export default function RulesPage() { variant="light" className={badgeClasses.statsBadge} styles={{ label: { textTransform: "none" } }} - leftSection={} + leftSection={} > last run {humanizeDurationRelative(g.lastEvaluation, now())} @@ -84,7 +85,7 @@ export default function RulesPage() { variant="light" className={badgeClasses.statsBadge} styles={{ label: { textTransform: "none" } }} - leftSection={} + leftSection={} > took {humanizeDuration(parseFloat(g.evaluationTime) * 1000)} @@ -94,7 +95,7 @@ export default function RulesPage() { variant="transparent" className={badgeClasses.statsBadge} styles={{ label: { textTransform: "none" } }} - leftSection={} + leftSection={} > every {humanizeDuration(parseFloat(g.interval) * 1000)}{" "} @@ -102,7 +103,7 @@ export default function RulesPage() { {g.rules.length === 0 && ( - }> + }> No rules in rule group. )} @@ -150,7 +151,7 @@ export default function RulesPage() { variant="light" className={badgeClasses.statsBadge} styles={{ label: { textTransform: "none" } }} - leftSection={} + leftSection={} > {humanizeDurationRelative(r.lastEvaluation, now())} @@ -164,7 +165,9 @@ export default function RulesPage() { variant="light" className={badgeClasses.statsBadge} styles={{ label: { textTransform: "none" } }} - leftSection={} + leftSection={ + + } > {humanizeDuration( parseFloat(r.evaluationTime) * 1000 @@ -185,7 +188,7 @@ export default function RulesPage() { color="red" mt="sm" title="Rule failed to evaluate" - icon={} + icon={} > Error: {r.lastError} diff --git a/web/ui/mantine-ui/src/pages/StatusPage.tsx b/web/ui/mantine-ui/src/pages/StatusPage.tsx index 04d215cf5..71dc476a2 100644 --- a/web/ui/mantine-ui/src/pages/StatusPage.tsx +++ b/web/ui/mantine-ui/src/pages/StatusPage.tsx @@ -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>({ @@ -42,14 +44,8 @@ export default function StatusPage() { }; return ( - - - - - - Build information - - + + {Object.entries(buildinfo.data).map(([k, v]) => ( @@ -60,14 +56,8 @@ export default function StatusPage() { ))}
-
- - - - - Runtime information - - + + {Object.entries(runtimeinfo.data).map(([k, v]) => { @@ -84,7 +74,7 @@ export default function StatusPage() { })}
-
-
+ + ); } diff --git a/web/ui/mantine-ui/src/pages/TSDBStatusPage.tsx b/web/ui/mantine-ui/src/pages/TSDBStatusPage.tsx index 721ac6904..cf7851c16 100644 --- a/web/ui/mantine-ui/src/pages/TSDBStatusPage.tsx +++ b/web/ui/mantine-ui/src/pages/TSDBStatusPage.tsx @@ -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 ( - + {[ { title: "TSDB Head Status", @@ -70,10 +72,7 @@ export default function TSDBStatusPage() { formatAsCode: true, }, ].map(({ title, unit = "Count", stats, formatAsCode }) => ( - - - {title} - + @@ -82,24 +81,22 @@ export default function TSDBStatusPage() { - {stats.map(({ name, value }) => { - return ( - - - {formatAsCode ? {name} : name} - - {value} - - ); - })} + {stats.map(({ name, value }) => ( + + + {formatAsCode ? {name} : name} + + {value} + + ))}
-
+ ))} -
+ ); } diff --git a/web/ui/mantine-ui/src/pages/query/DataTable.tsx b/web/ui/mantine-ui/src/pages/query/DataTable.tsx index 5ccc8cb95..375b033ed 100644 --- a/web/ui/mantine-ui/src/pages/query/DataTable.tsx +++ b/web/ui/mantine-ui/src/pages/query/DataTable.tsx @@ -64,7 +64,7 @@ const DataTable: FC = ({ result.length > maxDisplayableSeries && ( } + icon={} title="Showing limited results" > Fetched {data.result.length} metrics, only displaying first{" "} @@ -76,10 +76,7 @@ const DataTable: FC = ({ )} {!doFormat && ( - } - > + }> Showing more than {maxFormattableSeries} series, turning off label formatting to improve rendering performance. @@ -166,7 +163,7 @@ const DataTable: FC = ({ } + icon={} > Invalid result value type diff --git a/web/ui/mantine-ui/src/pages/query/ExplainViews/BinaryExpr/VectorVector.tsx b/web/ui/mantine-ui/src/pages/query/ExplainViews/BinaryExpr/VectorVector.tsx index 6735d1320..24f754393 100644 --- a/web/ui/mantine-ui/src/pages/query/ExplainViews/BinaryExpr/VectorVector.tsx +++ b/web/ui/mantine-ui/src/pages/query/ExplainViews/BinaryExpr/VectorVector.tsx @@ -381,11 +381,7 @@ const VectorVectorBinaryExprExplainView: FC< {numGroups > Object.keys(matchGroups).length && ( - } - > + }> Too many match groups to display, only showing{" "} {Object.keys(matchGroups).length} out of {numGroups} groups.
@@ -397,11 +393,7 @@ const VectorVectorBinaryExprExplainView: FC< )} {errCount > 0 && ( - } - > + }> Found matching issues in {errCount} match group {errCount > 1 ? "s" : ""}. See below for per-group error details. @@ -642,7 +634,7 @@ const VectorVectorBinaryExprExplainView: FC< color="red" mb="md" title="Error in match group below" - icon={} + icon={} > {explainError(node, mg, error)} diff --git a/web/ui/mantine-ui/src/pages/query/ExpressionInput.tsx b/web/ui/mantine-ui/src/pages/query/ExpressionInput.tsx index dce05c181..a4b26cd91 100644 --- a/web/ui/mantine-ui/src/pages/query/ExpressionInput.tsx +++ b/web/ui/mantine-ui/src/pages/query/ExpressionInput.tsx @@ -7,7 +7,6 @@ import { Loader, Menu, Modal, - rem, Skeleton, useComputedColorScheme, } from "@mantine/core"; @@ -70,6 +69,7 @@ import { useSettings } from "../../state/settingsSlice"; import MetricsExplorer from "./MetricsExplorer/MetricsExplorer"; import ErrorBoundary from "../../components/ErrorBoundary"; import { useAppSelector } from "../../state/hooks"; +import { inputIconStyle, menuIconStyle } from "../../styles"; const promqlExtension = new PromQLExtension(); @@ -224,25 +224,19 @@ const ExpressionInput: FC = ({ color="gray" aria-label="Show query options" > - + Query options - } + leftSection={} onClick={() => setShowMetricsExplorer(true)} > Explore metrics - } + leftSection={} onClick={() => formatQuery()} disabled={ isFormatting || expr === "" || expr === formatResult?.data @@ -251,18 +245,14 @@ const ExpressionInput: FC = ({ Format expression - } + leftSection={} onClick={() => setShowTree(!treeShown)} > {treeShown ? "Hide" : "Show"} tree view - } + leftSection={} onClick={removePanel} > Remove query diff --git a/web/ui/mantine-ui/src/pages/query/Graph.tsx b/web/ui/mantine-ui/src/pages/query/Graph.tsx index d037546cf..c25d5a98e 100644 --- a/web/ui/mantine-ui/src/pages/query/Graph.tsx +++ b/web/ui/mantine-ui/src/pages/query/Graph.tsx @@ -131,7 +131,7 @@ const Graph: FC = ({ } + icon={} > {error.message} @@ -146,7 +146,7 @@ const Graph: FC = ({ if (result.length === 0) { return ( - }> + }> This query returned no data. ); @@ -158,7 +158,7 @@ const Graph: FC = ({ } + icon={} > Note: Range vector selectors can't be graphed, so graphing the equivalent instant vector selector instead. diff --git a/web/ui/mantine-ui/src/pages/query/MetricsExplorer/LabelsExplorer.tsx b/web/ui/mantine-ui/src/pages/query/MetricsExplorer/LabelsExplorer.tsx index 29f159141..782fb5cf4 100644 --- a/web/ui/mantine-ui/src/pages/query/MetricsExplorer/LabelsExplorer.tsx +++ b/web/ui/mantine-ui/src/pages/query/MetricsExplorer/LabelsExplorer.tsx @@ -37,6 +37,7 @@ import { } from "@tabler/icons-react"; import { formatNode } from "../../../promql/format"; import classes from "./LabelsExplorer.module.css"; +import { buttonIconStyle } from "../../../styles"; type LabelsExplorerProps = { metricName: string; @@ -150,7 +151,7 @@ const LabelsExplorer: FC = ({ } + icon={} > Error: {error.message} @@ -177,7 +178,7 @@ const LabelsExplorer: FC = ({ variant="light" size="xs" onClick={() => insertText(serializeNode(selector))} - leftSection={} + leftSection={} title="Insert selector at cursor and close explorer" > Insert @@ -188,7 +189,11 @@ const LabelsExplorer: FC = ({ variant="light" size="xs" leftSection={ - copied ? : + copied ? ( + + ) : ( + + ) } onClick={copy} title="Copy selector to clipboard" @@ -228,7 +233,7 @@ const LabelsExplorer: FC = ({ variant="light" size="xs" onClick={hideLabelsExplorer} - leftSection={} + leftSection={} > Back to all metrics diff --git a/web/ui/mantine-ui/src/pages/query/QueryPage.tsx b/web/ui/mantine-ui/src/pages/query/QueryPage.tsx index d3131efa2..3baa77dfd 100644 --- a/web/ui/mantine-ui/src/pages/query/QueryPage.tsx +++ b/web/ui/mantine-ui/src/pages/query/QueryPage.tsx @@ -1,4 +1,4 @@ -import { Alert, Box, Button, Stack, rem } from "@mantine/core"; +import { Alert, Box, Button, Stack } from "@mantine/core"; import { IconAlertCircle, IconAlertTriangle, @@ -17,6 +17,7 @@ import { useEffect, useState } from "react"; import { InstantQueryResult } from "../../api/responseTypes/query"; import { humanizeDuration } from "../../lib/formatTime"; import { decodePanelOptionsFromURLParams } from "./urlStateEncoding"; +import { buttonIconStyle } from "../../styles"; export default function QueryPage() { const panels = useAppSelector((state) => state.queryPage.panels); @@ -80,9 +81,7 @@ export default function QueryPage() { {metricNamesError && ( - } + icon={} color="red" title="Error fetching metrics list" withCloseButton @@ -93,9 +92,7 @@ export default function QueryPage() { {timeError && ( - } + icon={} color="red" title="Error fetching server time" withCloseButton @@ -108,7 +105,7 @@ export default function QueryPage() { mb="sm" title="Server time is out of sync" color="red" - icon={} + icon={} onClose={() => setTimeDelta(0)} > Detected a time difference of{" "} @@ -131,7 +128,7 @@ export default function QueryPage() {