mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
vmui: allow displaying the full error message on click (#4760)
https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4719
This commit is contained in:
parent
336744a93e
commit
cf0077b552
7 changed files with 86 additions and 26 deletions
|
@ -36,7 +36,7 @@ const DateTimeInput: FC<DateTimeInputProps> = ({
|
|||
const [maskedValue, setMaskedValue] = useState(formatStringDate(value));
|
||||
const [focusToTime, setFocusToTime] = useState(false);
|
||||
const [awaitChangeForEnter, setAwaitChangeForEnter] = useState(false);
|
||||
const error = dayjs(maskedValue).isValid() ? "" : "Expected format: YYYY-MM-DD HH:mm:ss";
|
||||
const error = dayjs(maskedValue).isValid() ? "" : "Invalid date format";
|
||||
|
||||
const handleMaskedChange = (e: ChangeEvent<HTMLInputElement>) => {
|
||||
setMaskedValue(e.currentTarget.value);
|
||||
|
|
|
@ -3,6 +3,7 @@ import classNames from "classnames";
|
|||
import { useMemo } from "preact/compat";
|
||||
import { useAppState } from "../../../state/common/StateContext";
|
||||
import useDeviceDetect from "../../../hooks/useDeviceDetect";
|
||||
import TextFieldError from "./TextFieldError";
|
||||
import "./style.scss";
|
||||
|
||||
interface TextFieldProps {
|
||||
|
@ -132,12 +133,7 @@ const TextField: FC<TextFieldProps> = ({
|
|||
)
|
||||
}
|
||||
{label && <span className="vm-text-field__label">{label}</span>}
|
||||
<span
|
||||
className="vm-text-field__error"
|
||||
data-show={!!error}
|
||||
>
|
||||
{error}
|
||||
</span>
|
||||
<TextFieldError error={error}/>
|
||||
{helperText && !error && (
|
||||
<span className="vm-text-field__helper-text">
|
||||
{helperText}
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
import React, { FC, useEffect, useRef, useState } from "react";
|
||||
import useEventListener from "../../../hooks/useEventListener";
|
||||
import classNames from "classnames";
|
||||
import "./style.scss";
|
||||
|
||||
interface TextFieldErrorProps {
|
||||
error: string;
|
||||
}
|
||||
|
||||
const TextFieldError: FC<TextFieldErrorProps> = ({ error }) => {
|
||||
const errorRef = useRef<HTMLSpanElement>(null);
|
||||
const [isErrorTruncated, setIsErrorTruncated] = useState(false);
|
||||
const [showFull, setShowFull] = useState(false);
|
||||
|
||||
const checkIfTextTruncated = () => {
|
||||
const el = errorRef.current;
|
||||
if (el) {
|
||||
const { offsetWidth, scrollWidth, offsetHeight, scrollHeight } = el;
|
||||
// The "+1" is for the scrollbar in Firefox
|
||||
const overflowed = (offsetWidth + 1) < scrollWidth || (offsetHeight + 1) < scrollHeight;
|
||||
setIsErrorTruncated(overflowed);
|
||||
} else {
|
||||
setIsErrorTruncated(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleClickError = () => {
|
||||
if (!isErrorTruncated) return;
|
||||
setShowFull(true);
|
||||
setIsErrorTruncated(false);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setShowFull(false);
|
||||
checkIfTextTruncated();
|
||||
}, [errorRef, error]);
|
||||
|
||||
useEventListener("resize", checkIfTextTruncated);
|
||||
|
||||
return (
|
||||
<span
|
||||
className={classNames({
|
||||
"vm-text-field__error": true,
|
||||
"vm-text-field__error_overflowed": isErrorTruncated,
|
||||
"vm-text-field__error_full": showFull,
|
||||
})}
|
||||
data-show={!!error}
|
||||
ref={errorRef}
|
||||
onClick={handleClickError}
|
||||
>
|
||||
{error}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
export default TextFieldError;
|
|
@ -40,14 +40,9 @@
|
|||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2; /* number of lines to show */
|
||||
line-clamp: 2;
|
||||
-webkit-line-clamp: 1; /* number of lines to show */
|
||||
line-clamp: 1;
|
||||
-webkit-box-orient: vertical;
|
||||
|
||||
@media (max-width: 500px) {
|
||||
-webkit-line-clamp: 1; /* number of lines to show */
|
||||
line-clamp: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&__label {
|
||||
|
@ -56,10 +51,22 @@
|
|||
}
|
||||
|
||||
&__error {
|
||||
top: calc((100% - ($font-size-small/2)) - 2px);
|
||||
position: relative;
|
||||
top: calc($font-size-small/-2);
|
||||
width: fit-content;
|
||||
overflow-wrap: anywhere;
|
||||
color: $color-error;
|
||||
pointer-events: auto;
|
||||
user-select: text;
|
||||
|
||||
&_full {
|
||||
display: block;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
&_overflowed {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
&__helper-text {
|
||||
|
@ -117,9 +124,9 @@
|
|||
align-items: center;
|
||||
justify-content: center;
|
||||
max-width: 15px;
|
||||
top: auto;
|
||||
top: 0;
|
||||
left: $padding-small;
|
||||
height: 100%;
|
||||
height: 40px;
|
||||
position: absolute;
|
||||
color: $color-text-secondary;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ const Tooltip: FC<TooltipProps> = ({
|
|||
return () => {
|
||||
window.removeEventListener("scroll", onScrollWindow);
|
||||
};
|
||||
}, [isOpen]);
|
||||
}, [isOpen, title]);
|
||||
|
||||
const popperStyle = useMemo(() => {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
|
|
|
@ -52,6 +52,7 @@ input[type=number]::-webkit-outer-spin-button {
|
|||
left: $padding-global;
|
||||
bottom: $padding-global;
|
||||
z-index: 999;
|
||||
animation: vm-slide-snackbar 150ms cubic-bezier(0.280, 0.840, 0.420, 1.1);
|
||||
|
||||
&-content {
|
||||
display: grid;
|
||||
|
@ -71,15 +72,14 @@ input[type=number]::-webkit-outer-spin-button {
|
|||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
animation: vm-slide-snackbar 150ms cubic-bezier(0.280, 0.840, 0.420, 1.1);
|
||||
}
|
||||
|
||||
@keyframes vm-slide-snackbar {
|
||||
0% {
|
||||
transform: translateY(100%);
|
||||
}
|
||||
100% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
@keyframes vm-slide-snackbar {
|
||||
0% {
|
||||
transform: translateY(100%);
|
||||
}
|
||||
100% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ The following `tip` changes can be tested by building VictoriaMetrics components
|
|||
* FEATURE: [vmctl](https://docs.victoriametrics.com/vmctl.html): add support of `week` step for [time-based chunking migration](https://docs.victoriametrics.com/vmctl.html#using-time-based-chunking-of-migration). See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4738).
|
||||
* FEATURE: [vmctl](https://docs.victoriametrics.com/vmctl.html): do not add `/api/v1/read` suffix to remote read storage address defined by `--remote-read-src-addr` if a `--remote-read-disable-path-append` command-line flag is set. It allows an overriding path for remote-read API via `--remote-read-src-addr`. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4655).
|
||||
* FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): add warning in query field of vmui for partial data responses. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4721).
|
||||
* FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): allow displaying the full error message on click for trimmed error messages in vmui. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4719).
|
||||
* FEATURE: [Official Grafana dashboards for VictoriaMetrics](https://grafana.com/orgs/victoriametrics): add `Concurrent inserts` panel to vmagent's dasbhoard. The new panel supposed to show whether the number of concurrent inserts processed by vmagent isn't reaching the limit.
|
||||
* FEATURE: [Official Grafana dashboards for VictoriaMetrics](https://grafana.com/orgs/victoriametrics): add panels for absolute Mem and CPU usage by vmalert. See related issue [here](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4627).
|
||||
* FEATURE: [Official Grafana dashboards for VictoriaMetrics](https://grafana.com/orgs/victoriametrics): correctly calculate `Bytes per point` value for single-server and cluster VM dashboards. Before, the calculation mistakenly accounted for the number of entries in indexdb in denominator, which could have shown lower values than expected.
|
||||
|
|
Loading…
Reference in a new issue