From 7d1495056a9f5a8ba61550923aa687f0057ca84e Mon Sep 17 00:00:00 2001
From: Yury Molodov <yurymolodov@gmail.com>
Date: Tue, 18 Jul 2023 11:44:31 +0200
Subject: [PATCH] vmui: add tip to Explore Metrics page (#4615)

* feat: add tip to Explore Metrics page (#4248)

* fix: update description page
---
 .../ExploreMetricsHeader.tsx                  | 152 ++++++++++++------
 .../ExploreMetricsHeader/style.scss           |  20 +++
 app/vmui/packages/vmui/src/router/index.ts    |   2 +-
 app/vmui/packages/vmui/src/utils/storage.ts   |   1 +
 4 files changed, 122 insertions(+), 53 deletions(-)

diff --git a/app/vmui/packages/vmui/src/components/ExploreMetrics/ExploreMetricsHeader/ExploreMetricsHeader.tsx b/app/vmui/packages/vmui/src/components/ExploreMetrics/ExploreMetricsHeader/ExploreMetricsHeader.tsx
index 911178b46e..9d25581045 100644
--- a/app/vmui/packages/vmui/src/components/ExploreMetrics/ExploreMetricsHeader/ExploreMetricsHeader.tsx
+++ b/app/vmui/packages/vmui/src/components/ExploreMetrics/ExploreMetricsHeader/ExploreMetricsHeader.tsx
@@ -1,9 +1,15 @@
-import React, { FC, useMemo } from "preact/compat";
+import React, { FC, useEffect, useMemo } from "preact/compat";
 import Select from "../../Main/Select/Select";
 import "./style.scss";
 import { GRAPH_SIZES } from "../../../constants/graph";
 import classNames from "classnames";
 import useDeviceDetect from "../../../hooks/useDeviceDetect";
+import useBoolean from "../../../hooks/useBoolean";
+import { getFromStorage, saveToStorage } from "../../../utils/storage";
+import Alert from "../../Main/Alert/Alert";
+import Button from "../../Main/Button/Button";
+import { CloseIcon, TipIcon } from "../../Main/Icons";
+import Tooltip from "../../Main/Tooltip/Tooltip";
 
 interface ExploreMetricsHeaderProps {
   jobs: string[]
@@ -38,59 +44,101 @@ const ExploreMetricsHeader: FC<ExploreMetricsHeaderProps> = ({
   const noMetricsText = useMemo(() => job ? "" : "No metric names. Please select job", [job]);
   const { isMobile } = useDeviceDetect();
 
+  const {
+    value: showTips,
+    toggle: toggleShowTips,
+    setFalse: setHideTips,
+  } = useBoolean(getFromStorage("EXPLORE_METRICS_TIPS") !== "false");
+
+  useEffect(() => {
+    saveToStorage("EXPLORE_METRICS_TIPS", `${showTips}`);
+  }, [showTips]);
+
   return (
-    <div
-      className={classNames({
-        "vm-explore-metrics-header": true,
-        "vm-explore-metrics-header_mobile": isMobile,
-        "vm-block": true,
-        "vm-block_mobile": isMobile,
-      })}
-    >
-      <div className="vm-explore-metrics-header__job">
-        <Select
-          value={job}
-          list={jobs}
-          label="Job"
-          placeholder="Please select job"
-          onChange={onChangeJob}
-          autofocus={!job}
-          searchable
-        />
+    <>
+      <div
+        className={classNames({
+          "vm-explore-metrics-header": true,
+          "vm-explore-metrics-header_mobile": isMobile,
+          "vm-block": true,
+          "vm-block_mobile": isMobile,
+        })}
+      >
+        <div className="vm-explore-metrics-header__job">
+          <Select
+            value={job}
+            list={jobs}
+            label="Job"
+            placeholder="Please select job"
+            onChange={onChangeJob}
+            autofocus={!job}
+            searchable
+          />
+        </div>
+        <div className="vm-explore-metrics-header__instance">
+          <Select
+            value={instance}
+            list={instances}
+            label="Instance"
+            placeholder="Please select instance"
+            onChange={onChangeInstance}
+            noOptionsText={noInstanceText}
+            clearable
+            searchable
+          />
+        </div>
+        <div className="vm-explore-metrics-header__size">
+          <Select
+            label="Size graphs"
+            value={size}
+            list={sizeOptions}
+            onChange={onChangeSize}
+          />
+          <Tooltip title={`${showTips ? "Hide" : "Show"} tip`}>
+            <Button
+              variant="text"
+              color={showTips ? "warning" : "gray"}
+              startIcon={<TipIcon/>}
+              onClick={toggleShowTips}
+            />
+          </Tooltip>
+        </div>
+        <div className="vm-explore-metrics-header-metrics">
+          <Select
+            label={"Metrics"}
+            value={selectedMetrics}
+            list={names}
+            placeholder="Search metric name"
+            onChange={onToggleMetric}
+            noOptionsText={noMetricsText}
+            clearable
+            searchable
+          />
+        </div>
       </div>
-      <div className="vm-explore-metrics-header__instance">
-        <Select
-          value={instance}
-          list={instances}
-          label="Instance"
-          placeholder="Please select instance"
-          onChange={onChangeInstance}
-          noOptionsText={noInstanceText}
-          clearable
-          searchable
-        />
-      </div>
-      <div className="vm-explore-metrics-header__size">
-        <Select
-          label="Size graphs"
-          value={size}
-          list={sizeOptions}
-          onChange={onChangeSize}
-        />
-      </div>
-      <div className="vm-explore-metrics-header-metrics">
-        <Select
-          label={"Metrics"}
-          value={selectedMetrics}
-          list={names}
-          placeholder="Search metric name"
-          onChange={onToggleMetric}
-          noOptionsText={noMetricsText}
-          clearable
-          searchable
-        />
-      </div>
-    </div>
+
+      {showTips && (
+        <Alert variant={"warning"}>
+          <div className="vm-explore-metrics-header-description">
+            <p>
+              Please note: this page is solely designed for exploring Prometheus metrics.
+              Prometheus metrics always contain <code>job</code> and <code>instance</code> labels
+              (see <a
+                className="vm-link vm-link_colored"
+                href="https://prometheus.io/docs/concepts/jobs_instances/"
+              >these docs</a>), and this page relies on them as filters. <br/>
+              Please use this page for Prometheus metrics only, in accordance with their naming conventions.
+            </p>
+            <Button
+              variant="text"
+              size="small"
+              startIcon={<CloseIcon/>}
+              onClick={setHideTips}
+            />
+          </div>
+        </Alert>
+      )}
+    </>
   );
 };
 
diff --git a/app/vmui/packages/vmui/src/components/ExploreMetrics/ExploreMetricsHeader/style.scss b/app/vmui/packages/vmui/src/components/ExploreMetrics/ExploreMetricsHeader/style.scss
index 8eb2d0db38..4b598ed47f 100644
--- a/app/vmui/packages/vmui/src/components/ExploreMetrics/ExploreMetricsHeader/style.scss
+++ b/app/vmui/packages/vmui/src/components/ExploreMetrics/ExploreMetricsHeader/style.scss
@@ -26,6 +26,26 @@
   &__size {
     flex-grow: 1;
     min-width: 150px;
+    display: grid;
+    grid-template-columns: 1fr auto;
+    align-items: center;
+    gap: $padding-global;
+  }
+
+  &-description {
+    display: grid;
+    grid-template-columns: 1fr auto;
+    align-items: flex-start;
+    gap: $padding-small;
+
+    button {
+      color: inherit;
+      min-height: 29px;
+    }
+
+    code {
+      margin: 0 3px;
+    }
   }
 
   &-metrics {
diff --git a/app/vmui/packages/vmui/src/router/index.ts b/app/vmui/packages/vmui/src/router/index.ts
index 9bacbe6962..4e64461234 100644
--- a/app/vmui/packages/vmui/src/router/index.ts
+++ b/app/vmui/packages/vmui/src/router/index.ts
@@ -42,7 +42,7 @@ export const routerOptions: {[key: string]: RouterOptions} = {
     ...routerOptionsDefault
   },
   [router.metrics]: {
-    title: "Explore metrics",
+    title: "Explore Prometheus metrics",
     header: {
       tenant: true,
       stepControl: true,
diff --git a/app/vmui/packages/vmui/src/utils/storage.ts b/app/vmui/packages/vmui/src/utils/storage.ts
index 8a28d0298a..05734dfd2a 100644
--- a/app/vmui/packages/vmui/src/utils/storage.ts
+++ b/app/vmui/packages/vmui/src/utils/storage.ts
@@ -9,6 +9,7 @@ export type StorageKeys = "BASIC_AUTH_DATA"
     | "TIMEZONE"
     | "THEME"
     | "LOGS_LIMIT"
+    | "EXPLORE_METRICS_TIPS"
 
 export const saveToStorage = (key: StorageKeys, value: string | boolean | Record<string, unknown>): void => {
   if (value) {