From b29be5e6f894946a8ca82dba0732233ba98a424a Mon Sep 17 00:00:00 2001
From: Julius Volz <julius.volz@gmail.com>
Date: Sun, 1 Sep 2024 20:28:42 +0200
Subject: [PATCH] Add query button to rule expressions, improve styling

Signed-off-by: Julius Volz <julius.volz@gmail.com>
---
 .../src/components/RuleDefinition.module.css  |  9 +++++
 .../src/components/RuleDefinition.tsx         | 39 ++++++++++++++++---
 web/ui/mantine-ui/src/pages/AlertsPage.tsx    | 21 ++++++++--
 3 files changed, 61 insertions(+), 8 deletions(-)

diff --git a/web/ui/mantine-ui/src/components/RuleDefinition.module.css b/web/ui/mantine-ui/src/components/RuleDefinition.module.css
index d54a7d1b4f..15a8d4a420 100644
--- a/web/ui/mantine-ui/src/components/RuleDefinition.module.css
+++ b/web/ui/mantine-ui/src/components/RuleDefinition.module.css
@@ -4,3 +4,12 @@
     var(--mantine-color-gray-9)
   );
 }
+
+.queryButton {
+  opacity: 0;
+  transition: opacity 0.1s ease-in-out;
+}
+
+.codebox:hover .queryButton {
+  opacity: 1;
+}
diff --git a/web/ui/mantine-ui/src/components/RuleDefinition.tsx b/web/ui/mantine-ui/src/components/RuleDefinition.tsx
index dfc5c5d33f..0865f58ad9 100644
--- a/web/ui/mantine-ui/src/components/RuleDefinition.tsx
+++ b/web/ui/mantine-ui/src/components/RuleDefinition.tsx
@@ -1,5 +1,14 @@
-import { Badge, Box, Card, Group, useComputedColorScheme } from "@mantine/core";
-import { IconClockPause, IconClockPlay } from "@tabler/icons-react";
+import {
+  ActionIcon,
+  Badge,
+  Box,
+  Card,
+  Group,
+  rem,
+  Tooltip,
+  useComputedColorScheme,
+} from "@mantine/core";
+import { IconClockPause, IconClockPlay, IconSearch } from "@tabler/icons-react";
 import { FC } from "react";
 import { formatPrometheusDuration } from "../lib/formatTime";
 import codeboxClasses from "./RuleDefinition.module.css";
@@ -14,15 +23,17 @@ import {
 } from "../codemirror/theme";
 import { PromQLExtension } from "@prometheus-io/codemirror-promql";
 import { LabelBadges } from "./LabelBadges";
+import { useSettings } from "../state/settingsSlice";
 
 const promqlExtension = new PromQLExtension();
 
 const RuleDefinition: FC<{ rule: Rule }> = ({ rule }) => {
   const theme = useComputedColorScheme();
+  const { pathPrefix } = useSettings();
 
   return (
     <>
-      <Card p="xs" className={codeboxClasses.codebox} shadow="xs">
+      <Card p="xs" className={codeboxClasses.codebox} fz="sm" shadow="none">
         <CodeMirror
           basicSetup={false}
           value={rule.query}
@@ -37,9 +48,27 @@ const RuleDefinition: FC<{ rule: Rule }> = ({ rule }) => {
             EditorView.lineWrapping,
           ]}
         />
+
+        <Tooltip label={"Query rule expression"} withArrow position="top">
+          <ActionIcon
+            pos="absolute"
+            top={7}
+            right={7}
+            variant="light"
+            onClick={() => {
+              window.open(
+                `${pathPrefix}/query?g0.expr=${encodeURIComponent(rule.query)}&g0.tab=1`,
+                "_blank"
+              );
+            }}
+            className={codeboxClasses.queryButton}
+          >
+            <IconSearch style={{ width: rem(14) }} />
+          </ActionIcon>
+        </Tooltip>
       </Card>
       {rule.type === "alerting" && (
-        <Group mt="md" gap="xs">
+        <Group mt="lg" gap="xs">
           {rule.duration && (
             <Badge
               variant="light"
@@ -61,7 +90,7 @@ const RuleDefinition: FC<{ rule: Rule }> = ({ rule }) => {
         </Group>
       )}
       {rule.labels && Object.keys(rule.labels).length > 0 && (
-        <Box mt="md">
+        <Box mt="lg">
           <LabelBadges labels={rule.labels} />
         </Box>
       )}
diff --git a/web/ui/mantine-ui/src/pages/AlertsPage.tsx b/web/ui/mantine-ui/src/pages/AlertsPage.tsx
index 84f7ff1156..78e12a57d1 100644
--- a/web/ui/mantine-ui/src/pages/AlertsPage.tsx
+++ b/web/ui/mantine-ui/src/pages/AlertsPage.tsx
@@ -11,6 +11,7 @@ import {
   Alert,
   TextInput,
   Anchor,
+  Divider,
 } from "@mantine/core";
 import { useSuspenseAPIQuery } from "../api/api";
 import { AlertingRule, AlertingRulesResult } from "../api/responseTypes/rules";
@@ -352,7 +353,9 @@ export default function AlertsPage() {
                                             {a.state}
                                           </Badge>
                                         </Table.Td>
-                                        <Table.Td>
+                                        <Table.Td
+                                          style={{ whiteSpace: "nowrap" }}
+                                        >
                                           <Tooltip label={a.activeAt}>
                                             <Box>
                                               {humanizeDurationRelative(
@@ -363,12 +366,24 @@ export default function AlertsPage() {
                                             </Box>
                                           </Tooltip>
                                         </Table.Td>
-                                        <Table.Td>{a.value}</Table.Td>
+                                        <Table.Td
+                                          style={{ whiteSpace: "nowrap" }}
+                                        >
+                                          {isNaN(Number(a.value))
+                                            ? a.value
+                                            : Number(a.value)}
+                                        </Table.Td>
                                       </Table.Tr>
                                       {showAnnotations && (
                                         <Table.Tr>
                                           <Table.Td colSpan={4}>
-                                            <Table mt="md" mb="xl">
+                                            <Table
+                                              mt="md"
+                                              mb="xl"
+                                              withTableBorder
+                                              withColumnBorders
+                                              bg="var(--mantine-color-body)"
+                                            >
                                               <Table.Tbody>
                                                 {Object.entries(
                                                   a.annotations