mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
vmui: shortcut keys legend (#2971)
* feat: add shortcut modal * feat: add shortcut descriptions * app/vmselect/vmui: `make vmui-update` * docs/CHANGELOG.md: document the change Co-authored-by: Aliaksandr Valialkin <valyala@victoriametrics.com>
This commit is contained in:
parent
d7dc7c81e7
commit
dc52b283a3
13 changed files with 173 additions and 39 deletions
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"files": {
|
||||
"main.css": "./static/css/main.7e6d0c89.css",
|
||||
"main.js": "./static/js/main.e97de856.js",
|
||||
"main.css": "./static/css/main.9b22c3e0.css",
|
||||
"main.js": "./static/js/main.b8df40e9.js",
|
||||
"static/js/27.939f971b.chunk.js": "./static/js/27.939f971b.chunk.js",
|
||||
"index.html": "./index.html"
|
||||
},
|
||||
"entrypoints": [
|
||||
"static/css/main.7e6d0c89.css",
|
||||
"static/js/main.e97de856.js"
|
||||
"static/css/main.9b22c3e0.css",
|
||||
"static/js/main.b8df40e9.js"
|
||||
]
|
||||
}
|
|
@ -1 +1 @@
|
|||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="./favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="VM-UI is a metric explorer for Victoria Metrics"/><link rel="apple-touch-icon" href="./apple-touch-icon.png"/><link rel="icon" type="image/png" sizes="32x32" href="./favicon-32x32.png"><link rel="manifest" href="./manifest.json"/><title>VM UI</title><link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"/><script src="./dashboards/index.js" type="module"></script><script defer="defer" src="./static/js/main.e97de856.js"></script><link href="./static/css/main.7e6d0c89.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="./favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="VM-UI is a metric explorer for Victoria Metrics"/><link rel="apple-touch-icon" href="./apple-touch-icon.png"/><link rel="icon" type="image/png" sizes="32x32" href="./favicon-32x32.png"><link rel="manifest" href="./manifest.json"/><title>VM UI</title><link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"/><script src="./dashboards/index.js" type="module"></script><script defer="defer" src="./static/js/main.b8df40e9.js"></script><link href="./static/css/main.9b22c3e0.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|
|
@ -1 +0,0 @@
|
|||
body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif}code{font-family:source-code-pro,Menlo,Monaco,Consolas,Courier New,monospace}.MuiAccordionSummary-content{margin:0!important}.uplot,.uplot *,.uplot :after,.uplot :before{box-sizing:border-box}.uplot{font-family:system-ui,-apple-system,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5;width:-webkit-min-content;width:min-content}.u-title{font-size:18px;font-weight:700;text-align:center}.u-wrap{position:relative;-webkit-user-select:none;-ms-user-select:none;user-select:none}.u-over,.u-under{position:absolute}.u-under{overflow:hidden}.uplot canvas{display:block;height:100%;position:relative;width:100%}.u-axis{position:absolute}.u-legend{font-size:14px;margin:auto;text-align:center}.u-inline{display:block}.u-inline *{display:inline-block}.u-inline tr{margin-right:16px}.u-legend th{font-weight:600}.u-legend th>*{display:inline-block;vertical-align:middle}.u-legend .u-marker{background-clip:padding-box!important;height:1em;margin-right:4px;width:1em}.u-inline.u-live th:after{content:":";vertical-align:middle}.u-inline:not(.u-live) .u-value{display:none}.u-series>*{padding:4px}.u-series th{cursor:pointer}.u-legend .u-off>*{opacity:.3}.u-select{background:rgba(0,0,0,.07)}.u-cursor-x,.u-cursor-y,.u-select{pointer-events:none;position:absolute}.u-cursor-x,.u-cursor-y{left:0;top:0;will-change:transform;z-index:100}.u-hz .u-cursor-x,.u-vt .u-cursor-y{border-right:1px dashed #607d8b;height:100%}.u-hz .u-cursor-y,.u-vt .u-cursor-x{border-bottom:1px dashed #607d8b;width:100%}.u-cursor-pt{background-clip:padding-box!important;border:0 solid;border-radius:50%;left:0;pointer-events:none;position:absolute;top:0;will-change:transform;z-index:100}.u-axis.u-off,.u-cursor-pt.u-off,.u-cursor-x.u-off,.u-cursor-y.u-off,.u-select.u-off,.u-tooltip{display:none}.u-tooltip{grid-gap:12px;word-wrap:break-word;background:rgba(57,57,57,.9);border-radius:4px;color:#fff;font-family:monospace;font-size:10px;font-weight:500;line-height:1.4em;max-width:300px;padding:8px;pointer-events:none;position:absolute;z-index:100}.u-tooltip-data{align-items:center;display:flex;flex-wrap:wrap;font-size:11px;line-height:150%}.u-tooltip-data__value{font-weight:700;padding:4px}.u-tooltip__info{grid-gap:4px;display:grid}.u-tooltip__marker{height:12px;margin-right:4px;width:12px}.legendWrapper{cursor:default;display:flex;flex-wrap:wrap;margin-top:20px;position:relative}.legendGroup{margin:0 12px 24px 0;padding:10px 6px}.legendGroupTitle{align-items:center;border-bottom:1px solid #ecebe6;display:flex;font-size:11px;margin-bottom:5px;padding:0 10px 5px}.legendGroupQuery{font-weight:700;margin-right:4px}.legendGroupLine{margin-right:10px}.legendItem{grid-gap:6px;align-items:start;background-color:#fff;cursor:pointer;display:grid;grid-template-columns:auto auto;justify-content:start;padding:7px 50px 7px 10px;transition:.2s ease}.legendItemHide{opacity:.5;text-decoration:line-through}.legendItem:hover{background-color:rgba(0,0,0,.1)}.legendMarker{border-style:solid;border-width:2px;box-sizing:border-box;height:12px;transition:.2s ease;width:12px}.legendLabel{font-size:11px;font-weight:400;line-height:12px}.legendFreeFields{cursor:pointer;padding:3px}.legendFreeFields:hover{text-decoration:underline}.legendFreeFields:not(:last-child):after{content:","}.legendWrapperHotkey{align-items:center;display:flex;font-size:11px}.legendWrapperHotkey p{margin-right:20px}.legendWrapperHotkey code{word-wrap:break-word;background-color:#f2f2f2;border:1px solid #dedede;border-radius:2px;color:#0a0a0a;display:inline;font-size:10px;font-weight:400;max-width:100%;padding:4px 6px}.panelDescription ul{line-height:2.2}.panelDescription a{color:#fff}.panelDescription code{background-color:rgba(0,0,0,.3);border-radius:2px;color:#fff;display:inline;font-size:inherit;font-weight:400;max-width:100%;padding:4px 6px}
|
1
app/vmselect/vmui/static/css/main.9b22c3e0.css
Normal file
1
app/vmselect/vmui/static/css/main.9b22c3e0.css
Normal file
|
@ -0,0 +1 @@
|
|||
body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif}code{font-family:source-code-pro,Menlo,Monaco,Consolas,Courier New,monospace}.MuiAccordionSummary-content{margin:0!important}.shortcut-key{align-items:center;border:1px solid #dedede;border-radius:4px;cursor:default;display:inline-flex;font-size:10px;justify-content:center;line-height:22px;padding:2px 6px 0;text-align:center;white-space:nowrap}.uplot,.uplot *,.uplot :after,.uplot :before{box-sizing:border-box}.uplot{font-family:system-ui,-apple-system,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5;width:-webkit-min-content;width:min-content}.u-title{font-size:18px;font-weight:700;text-align:center}.u-wrap{position:relative;-webkit-user-select:none;-ms-user-select:none;user-select:none}.u-over,.u-under{position:absolute}.u-under{overflow:hidden}.uplot canvas{display:block;height:100%;position:relative;width:100%}.u-axis{position:absolute}.u-legend{font-size:14px;margin:auto;text-align:center}.u-inline{display:block}.u-inline *{display:inline-block}.u-inline tr{margin-right:16px}.u-legend th{font-weight:600}.u-legend th>*{display:inline-block;vertical-align:middle}.u-legend .u-marker{background-clip:padding-box!important;height:1em;margin-right:4px;width:1em}.u-inline.u-live th:after{content:":";vertical-align:middle}.u-inline:not(.u-live) .u-value{display:none}.u-series>*{padding:4px}.u-series th{cursor:pointer}.u-legend .u-off>*{opacity:.3}.u-select{background:rgba(0,0,0,.07)}.u-cursor-x,.u-cursor-y,.u-select{pointer-events:none;position:absolute}.u-cursor-x,.u-cursor-y{left:0;top:0;will-change:transform;z-index:100}.u-hz .u-cursor-x,.u-vt .u-cursor-y{border-right:1px dashed #607d8b;height:100%}.u-hz .u-cursor-y,.u-vt .u-cursor-x{border-bottom:1px dashed #607d8b;width:100%}.u-cursor-pt{background-clip:padding-box!important;border:0 solid;border-radius:50%;left:0;pointer-events:none;position:absolute;top:0;will-change:transform;z-index:100}.u-axis.u-off,.u-cursor-pt.u-off,.u-cursor-x.u-off,.u-cursor-y.u-off,.u-select.u-off,.u-tooltip{display:none}.u-tooltip{grid-gap:12px;word-wrap:break-word;background:rgba(57,57,57,.9);border-radius:4px;color:#fff;font-family:monospace;font-size:10px;font-weight:500;line-height:1.4em;max-width:300px;padding:8px;pointer-events:none;position:absolute;z-index:100}.u-tooltip-data{align-items:center;display:flex;flex-wrap:wrap;font-size:11px;line-height:150%}.u-tooltip-data__value{font-weight:700;padding:4px}.u-tooltip__info{grid-gap:4px;display:grid}.u-tooltip__marker{height:12px;margin-right:4px;width:12px}.legendWrapper{cursor:default;display:flex;flex-wrap:wrap;margin-top:20px;position:relative}.legendGroup{margin:0 12px 0 0;padding:10px 6px}.legendGroupTitle{align-items:center;border-bottom:1px solid #ecebe6;display:flex;font-size:11px;margin-bottom:5px;padding:0 10px 5px}.legendGroupQuery{font-weight:700;margin-right:4px}.legendGroupLine{margin-right:10px}.legendItem{grid-gap:6px;align-items:start;background-color:#fff;cursor:pointer;display:grid;grid-template-columns:auto auto;justify-content:start;padding:7px 50px 7px 10px;transition:.2s ease}.legendItemHide{opacity:.5;text-decoration:line-through}.legendItem:hover{background-color:rgba(0,0,0,.1)}.legendMarker{border-style:solid;border-width:2px;box-sizing:border-box;height:12px;transition:.2s ease;width:12px}.legendLabel{font-size:11px;font-weight:400;line-height:12px}.legendFreeFields{cursor:pointer;padding:3px}.legendFreeFields:hover{text-decoration:underline}.legendFreeFields:not(:last-child):after{content:","}.panelDescription ul{line-height:2.2}.panelDescription a{color:#fff}.panelDescription code{background-color:rgba(0,0,0,.3);border-radius:2px;color:#fff;display:inline;font-size:inherit;font-weight:400;max-width:100%;padding:4px 6px}
|
2
app/vmselect/vmui/static/js/main.b8df40e9.js
Normal file
2
app/vmselect/vmui/static/js/main.b8df40e9.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -16,6 +16,7 @@ import router, {RouterOptions, routerOptions} from "../../router/index";
|
|||
import DatePicker from "../Main/DatePicker/DatePicker";
|
||||
import {useCardinalityState, useCardinalityDispatch} from "../../state/cardinality/CardinalityStateContext";
|
||||
import {useEffect} from "react";
|
||||
import ShortcutKeys from "../ShortcutKeys/ShortcutKeys";
|
||||
|
||||
const classes = {
|
||||
logo: {
|
||||
|
@ -110,7 +111,7 @@ const Header: FC = () => {
|
|||
to={`${router.cardinality}${search}`}/>
|
||||
</Tabs>
|
||||
</Box>
|
||||
<Box display="grid" gridTemplateColumns="repeat(3, auto)" gap={1} alignItems="center" ml="auto" mr={0}>
|
||||
<Box display="flex" gap={1} alignItems="center" ml="auto" mr={0}>
|
||||
{headerSetup?.timeSelector && <TimeSelector/>}
|
||||
{headerSetup?.datePicker && (
|
||||
<DatePicker
|
||||
|
@ -120,6 +121,7 @@ const Header: FC = () => {
|
|||
)}
|
||||
{headerSetup?.executionControls && <ExecutionControls/>}
|
||||
{headerSetup?.globalSettings && <GlobalSettings/>}
|
||||
<ShortcutKeys/>
|
||||
</Box>
|
||||
</Toolbar>
|
||||
</AppBar>;
|
||||
|
|
|
@ -70,11 +70,6 @@ const Legend: FC<LegendProps> = ({labels, query, onChange}) => {
|
|||
</div>
|
||||
</div>)}
|
||||
</div>
|
||||
<div className="legendWrapperHotkey">
|
||||
<p><code>Left click</code> - select series</p>
|
||||
<p><code>Ctrl</code> + <code>Left click</code> - toggle multiple series</p>
|
||||
</div>
|
||||
|
||||
</>;
|
||||
};
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
}
|
||||
|
||||
.legendGroup {
|
||||
margin: 0 12px 24px 0;
|
||||
margin: 0 12px 0 0;
|
||||
padding: 10px 6px;
|
||||
}
|
||||
|
||||
|
@ -77,26 +77,3 @@
|
|||
.legendFreeFields:not(:last-child):after {
|
||||
content: ",";
|
||||
}
|
||||
|
||||
.legendWrapperHotkey {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.legendWrapperHotkey p {
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.legendWrapperHotkey code {
|
||||
display: inline;
|
||||
max-width: 100%;
|
||||
padding: 4px 6px;
|
||||
border: 1px solid #dedede;
|
||||
background-color: #f2f2f2;
|
||||
border-radius: 2px;
|
||||
font-weight: 400;
|
||||
font-size: 10px;
|
||||
color: #0a0a0a;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,145 @@
|
|||
import React, {FC, useState} from "preact/compat";
|
||||
import Tooltip from "@mui/material/Tooltip";
|
||||
import Button from "@mui/material/Button";
|
||||
import Modal from "@mui/material/Modal";
|
||||
import Box from "@mui/material/Box";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import IconButton from "@mui/material/IconButton";
|
||||
import KeyboardIcon from "@mui/icons-material/Keyboard";
|
||||
import CloseIcon from "@mui/icons-material/Close";
|
||||
import Divider from "@mui/material/Divider";
|
||||
import {isMacOs} from "../../utils/detect-os";
|
||||
|
||||
const modalStyle = {
|
||||
position: "absolute" as const,
|
||||
top: "50%",
|
||||
left: "50%",
|
||||
p: 3,
|
||||
minWidth: "300px",
|
||||
maxWidth: "800px",
|
||||
borderRadius: "4px",
|
||||
bgcolor: "background.paper",
|
||||
transform: "translate(-50%, -50%)",
|
||||
};
|
||||
|
||||
const ctrlMeta = isMacOs() ? "Cmd" : "Ctrl";
|
||||
|
||||
const keyList = [
|
||||
{
|
||||
title: "Query",
|
||||
list: [
|
||||
{
|
||||
keys: ["Enter"],
|
||||
description: "Run"
|
||||
},
|
||||
{
|
||||
keys: ["Shift", "Enter"],
|
||||
description: "Multi-line queries"
|
||||
},
|
||||
{
|
||||
keys: [ctrlMeta, "Arrow Up"],
|
||||
description: "Previous command from the Query history"
|
||||
},
|
||||
{
|
||||
keys: [ctrlMeta, "Arrow Down"],
|
||||
description: "Next command from the Query history"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Graph",
|
||||
list: [
|
||||
{
|
||||
keys: [ctrlMeta, "Scroll Up"],
|
||||
description: "Zoom in"
|
||||
},
|
||||
{
|
||||
keys: [ctrlMeta, "Scroll Down"],
|
||||
description: "Zoom out"
|
||||
},
|
||||
{
|
||||
keys: [ctrlMeta, "Click and Drag"],
|
||||
description: "Move the graph left/right"
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Legend",
|
||||
list: [
|
||||
{
|
||||
keys: ["Mouse Click"],
|
||||
description: "Select series"
|
||||
},
|
||||
{
|
||||
keys: [ctrlMeta, "Mouse Click"],
|
||||
description: "Toggle multiple series"
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
const ShortcutKeys: FC = () => {
|
||||
const [openList, setOpenList] = useState(false);
|
||||
|
||||
return <>
|
||||
<Tooltip title={"Shortcut keys"}>
|
||||
<Button variant="contained" color="primary"
|
||||
sx={{
|
||||
color: "white",
|
||||
border: "1px solid rgba(0, 0, 0, 0.2)",
|
||||
minWidth: "34px",
|
||||
padding: "6px 8px",
|
||||
boxShadow: "none",
|
||||
}}
|
||||
startIcon={<KeyboardIcon style={{marginRight: "-8px", marginLeft: "4px"}}/>}
|
||||
onClick={() => setOpenList(prev => !prev)}>
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Modal open={openList} onClose={() => setOpenList(false)}>
|
||||
<Box sx={modalStyle}>
|
||||
<Box display="grid" gridTemplateColumns="1fr auto" alignItems="center" mb={2}>
|
||||
<Typography id="modal-modal-title" variant="h6" component="h2">
|
||||
Shortcut keys
|
||||
</Typography>
|
||||
<IconButton size="small" onClick={() => setOpenList(false)}>
|
||||
<CloseIcon/>
|
||||
</IconButton>
|
||||
</Box>
|
||||
<Box>
|
||||
{keyList.map(section => (
|
||||
<Box key={section.title} mb={3}>
|
||||
<Typography variant="body1" component="h3" fontWeight="bold" mb={0.5}>
|
||||
{section.title}
|
||||
</Typography>
|
||||
<Divider sx={{mb: 1}}/>
|
||||
<Box>
|
||||
{section.list.map(l => (
|
||||
<Box
|
||||
key={l.keys.join("+")}
|
||||
display="grid"
|
||||
gridTemplateColumns="160px 1fr"
|
||||
alignItems="center"
|
||||
mb={1}
|
||||
>
|
||||
<Box display="flex" alignItems="center" fontSize="10px" gap={"4px"}>
|
||||
{l.keys.map((k, i) => (
|
||||
<>
|
||||
<code key={k} className="shortcut-key">{k}</code> {i !== l.keys.length - 1 ? "+" : ""}
|
||||
</>
|
||||
))}
|
||||
</Box>
|
||||
<Typography variant="body2" component="p">
|
||||
{l.description}
|
||||
</Typography>
|
||||
</Box>
|
||||
))}
|
||||
</Box>
|
||||
</Box>
|
||||
))}
|
||||
</Box>
|
||||
</Box>
|
||||
</Modal>
|
||||
</>;
|
||||
};
|
||||
|
||||
export default ShortcutKeys;
|
|
@ -14,4 +14,18 @@ code {
|
|||
|
||||
.MuiAccordionSummary-content {
|
||||
margin: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.shortcut-key {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 2px 6px 0;
|
||||
text-align: center;
|
||||
border-radius: 4px;
|
||||
font-size: 10px;
|
||||
line-height: 22px;
|
||||
white-space: nowrap;
|
||||
border: 1px solid #dedede;
|
||||
cursor: default;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ The following tip changes can be tested by building VictoriaMetrics components f
|
|||
* FEATURE: [vmagent](https://docs.victoriametrics.com/vmagent.html): add support for MX record types in [dns_sd_configs](https://docs.victoriametrics.com/sd_configs.html#dns_sd_configs) in the same way as Prometheus 2.38 [does](https://github.com/prometheus/prometheus/pull/10099).
|
||||
* FEATURE: [vmagent](https://docs.victoriametrics.com/vmagent.html): add `__meta_kubernetes_service_port_number` meta-label for `role: service` in [kubernetes_sd_configs](https://docs.victoriametrics.com/sd_configs.html#kubernetes_sd_configs) in the same way as Prometheus 2.38 [does](https://github.com/prometheus/prometheus/pull/11002).
|
||||
* FEATURE: [vmagent](https://docs.victoriametrics.com/vmagent.html): add `__meta_kubernetes_pod_container_image` meta-label for `role: pod` in [kubernetes_sd_configs](https://docs.victoriametrics.com/sd_configs.html#kubernetes_sd_configs) in the same way as Prometheus 2.38 [does](https://github.com/prometheus/prometheus/pull/11034).
|
||||
* FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): add a legend in the top right corner for shortcut keys. See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2813).
|
||||
* FEATURE: [vmalert](https://docs.victoriametrics.com/vmalert.html): add `toTime()` template function in the same way as Prometheus 2.38 [does](https://github.com/prometheus/prometheus/pull/10993). See [these docs](https://prometheus.io/docs/prometheus/latest/configuration/template_reference/#numbers).
|
||||
|
||||
* BUGFIX: prevent from excess CPU usage when the storage enters [read-only mode](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#readonly-mode).
|
||||
|
|
Loading…
Reference in a new issue