mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
vmui: change logic autocomplete (#2196)
* fix: change autocomplete display logic * fix: change z-index for labels of input fields * fix: change autocomplete display logic * wip * wip Co-authored-by: Aliaksandr Valialkin <valyala@victoriametrics.com>
This commit is contained in:
parent
4211f85e52
commit
cdd632985f
7 changed files with 52 additions and 34 deletions
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"files": {
|
||||
"main.css": "./static/css/main.098d452b.css",
|
||||
"main.js": "./static/js/main.c945b173.js",
|
||||
"main.js": "./static/js/main.afc823de.js",
|
||||
"static/js/27.939f971b.chunk.js": "./static/js/27.939f971b.chunk.js",
|
||||
"index.html": "./index.html"
|
||||
},
|
||||
"entrypoints": [
|
||||
"static/css/main.098d452b.css",
|
||||
"static/js/main.c945b173.js"
|
||||
"static/js/main.afc823de.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 defer="defer" src="./static/js/main.c945b173.js"></script><link href="./static/css/main.098d452b.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 defer="defer" src="./static/js/main.afc823de.js"></script><link href="./static/css/main.098d452b.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|
2
app/vmselect/vmui/static/js/main.afc823de.js
Normal file
2
app/vmselect/vmui/static/js/main.afc823de.js
Normal file
File diff suppressed because one or more lines are too long
|
@ -6,7 +6,7 @@
|
|||
* @license MIT
|
||||
*/
|
||||
|
||||
/** @license MUI v5.4.1
|
||||
/** @license MUI v5.4.2
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
File diff suppressed because one or more lines are too long
|
@ -31,21 +31,23 @@ const QueryEditor: FC<QueryEditorProps> = ({
|
|||
queryOptions
|
||||
}) => {
|
||||
|
||||
const [downMetaKeys, setDownMetaKeys] = useState<string[]>([]);
|
||||
const [focusField, setFocusField] = useState(false);
|
||||
const [focusOption, setFocusOption] = useState(-1);
|
||||
const autocompleteAnchorEl = useRef<HTMLDivElement>(null);
|
||||
const wrapperEl = useRef<HTMLUListElement>(null);
|
||||
|
||||
const openAutocomplete = useMemo(() => {
|
||||
return !(!autocomplete || downMetaKeys.length || query.length < 2 || !focusField);
|
||||
}, [query, downMetaKeys, autocomplete, focusField]);
|
||||
const words = (query.match(/[a-zA-Z_:.][a-zA-Z0-9_:.]*/gm) || []).length;
|
||||
return !(!autocomplete || query.length < 2 || words > 1 || !focusField);
|
||||
}, [query, autocomplete, focusField]);
|
||||
|
||||
const actualOptions = useMemo(() => {
|
||||
setFocusOption(0);
|
||||
if (!openAutocomplete) return [];
|
||||
try {
|
||||
const regexp = new RegExp(String(query), "i");
|
||||
return queryOptions.filter((item) => regexp.test(item) && item !== query);
|
||||
const options = queryOptions.filter((item) => regexp.test(item) && (item !== query));
|
||||
return options.sort((a,b) => (a.match(regexp)?.index || 0) - (b.match(regexp)?.index || 0));
|
||||
} catch (e) {
|
||||
return [];
|
||||
}
|
||||
|
@ -53,31 +55,38 @@ const QueryEditor: FC<QueryEditorProps> = ({
|
|||
|
||||
const handleKeyDown = (e: KeyboardEvent<HTMLDivElement>) => {
|
||||
const {key, ctrlKey, metaKey, shiftKey} = e;
|
||||
if (ctrlKey || metaKey) setDownMetaKeys([...downMetaKeys, e.key]);
|
||||
if (key === "ArrowUp" && openAutocomplete && actualOptions.length) {
|
||||
e.preventDefault();
|
||||
setFocusOption((prev) => prev === 0 ? 0 : prev - 1);
|
||||
} else if (key === "ArrowDown" && openAutocomplete && actualOptions.length) {
|
||||
e.preventDefault();
|
||||
setFocusOption((prev) => prev >= actualOptions.length - 1 ? actualOptions.length - 1 : prev + 1);
|
||||
} else if (key === "Enter" && openAutocomplete && actualOptions.length && !shiftKey) {
|
||||
e.preventDefault();
|
||||
setQuery(actualOptions[focusOption], index);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
const handleKeyUp = (e: KeyboardEvent<HTMLDivElement>) => {
|
||||
const {key, ctrlKey, metaKey} = e;
|
||||
if (downMetaKeys.includes(key)) setDownMetaKeys(downMetaKeys.filter(k => k !== key));
|
||||
const ctrlMetaKey = ctrlKey || metaKey;
|
||||
if (key === "Enter" && ctrlMetaKey) {
|
||||
runQuery();
|
||||
} else if (key === "ArrowUp" && ctrlMetaKey) {
|
||||
const arrowUp = key === "ArrowUp";
|
||||
const arrowDown = key === "ArrowDown";
|
||||
const enter = key === "Enter";
|
||||
|
||||
const hasAutocomplete = openAutocomplete && actualOptions.length;
|
||||
|
||||
if ((arrowUp || arrowDown || enter) && (hasAutocomplete || ctrlMetaKey)) {
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
// ArrowUp
|
||||
if (arrowUp && hasAutocomplete && !ctrlMetaKey) {
|
||||
setFocusOption((prev) => prev === 0 ? 0 : prev - 1);
|
||||
} else if (arrowUp && ctrlMetaKey) {
|
||||
setHistoryIndex(-1, index);
|
||||
} else if (key === "ArrowDown" && ctrlMetaKey) {
|
||||
}
|
||||
|
||||
// ArrowDown
|
||||
if (arrowDown && hasAutocomplete && !ctrlMetaKey) {
|
||||
setFocusOption((prev) => prev >= actualOptions.length - 1 ? actualOptions.length - 1 : prev + 1);
|
||||
} else if (arrowDown && ctrlMetaKey) {
|
||||
setHistoryIndex(1, index);
|
||||
}
|
||||
|
||||
// Enter
|
||||
if (enter && hasAutocomplete && !shiftKey && !ctrlMetaKey) {
|
||||
setQuery(actualOptions[focusOption], index);
|
||||
} else if (enter && ctrlKey) {
|
||||
runQuery();
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -94,8 +103,16 @@ const QueryEditor: FC<QueryEditorProps> = ({
|
|||
multiline
|
||||
error={!!error}
|
||||
onFocus={() => setFocusField(true)}
|
||||
onBlur={() => setFocusField(false)}
|
||||
onKeyUp={handleKeyUp}
|
||||
onBlur={(e) => {
|
||||
const autocompleteItem = e.relatedTarget?.id || "";
|
||||
const itemIndex = actualOptions.indexOf(autocompleteItem.replace("$autocomplete$", ""));
|
||||
if (itemIndex !== -1) {
|
||||
setQuery(actualOptions[itemIndex], index);
|
||||
e.target.focus();
|
||||
} else {
|
||||
setFocusField(false);
|
||||
}
|
||||
}}
|
||||
onKeyDown={handleKeyDown}
|
||||
onChange={(e) => setQuery(e.target.value, index)}
|
||||
/>
|
||||
|
@ -103,7 +120,7 @@ const QueryEditor: FC<QueryEditorProps> = ({
|
|||
<Paper elevation={3} sx={{ maxHeight: 300, overflow: "auto" }}>
|
||||
<MenuList ref={wrapperEl} dense>
|
||||
{actualOptions.map((item, i) =>
|
||||
<MenuItem key={item} sx={{bgcolor: `rgba(0, 0, 0, ${i === focusOption ? 0.12 : 0})`}}>
|
||||
<MenuItem id={`$autocomplete$${item}`} key={item} sx={{bgcolor: `rgba(0, 0, 0, ${i === focusOption ? 0.12 : 0})`}}>
|
||||
{item}
|
||||
</MenuItem>)}
|
||||
</MenuList>
|
||||
|
|
|
@ -28,7 +28,8 @@ const THEME = createTheme({
|
|||
root: {
|
||||
fontSize: "12px",
|
||||
letterSpacing: "normal",
|
||||
lineHeight: "1"
|
||||
lineHeight: "1",
|
||||
zIndex: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue