vmui: improve the appearance of the trace (#5091)

This commit is contained in:
Yury Molodov 2023-10-02 21:24:03 +02:00 committed by GitHub
parent 34961dd4b8
commit 133425f0c0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 108 additions and 23 deletions

View file

@ -32,6 +32,10 @@ $padding-modal: $padding-medium;
&-header {
padding: $padding-small $padding-small $padding-small $padding-global;
margin-bottom: $padding-global;
&__title {
max-width: 80vw;
}
}
&-body {
@ -69,6 +73,10 @@ $padding-modal: $padding-medium;
&__title {
font-weight: bold;
user-select: none;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 50vw;
}
&__close {

View file

@ -8,8 +8,10 @@ import classNames from "classnames";
import { useAppState } from "../../../state/common/StateContext";
import useDeviceDetect from "../../../hooks/useDeviceDetect";
import Button from "../../Main/Button/Button";
import { humanizeSeconds } from "../../../utils/time";
interface RecursiveProps {
isRoot?: boolean;
trace: Trace;
totalMsec: number;
}
@ -18,7 +20,7 @@ interface OpenLevels {
[x: number]: boolean
}
const NestedNav: FC<RecursiveProps> = ({ trace, totalMsec }) => {
const NestedNav: FC<RecursiveProps> = ({ isRoot, trace, totalMsec }) => {
const { isDarkTheme } = useAppState();
const { isMobile } = useDeviceDetect();
const [openLevels, setOpenLevels] = useState({} as OpenLevels);
@ -27,6 +29,8 @@ const NestedNav: FC<RecursiveProps> = ({ trace, totalMsec }) => {
const [isExpanded, setIsExpanded] = useState(false);
const [showFullMessage, setShowFullMessage] = useState(false);
const duration = humanizeSeconds(trace.duration / 1000) || `${trace.duration}ms`;
useEffect(() => {
if (!messageRef.current) return;
const contentElement = messageRef.current;
@ -40,24 +44,29 @@ const NestedNav: FC<RecursiveProps> = ({ trace, totalMsec }) => {
setShowFullMessage(prev => !prev);
};
const hasChildren = trace.children && !!trace.children.length;
const progress = trace.duration / totalMsec * 100;
const handleListClick = (level: number) => () => {
if (!hasChildren) return;
setOpenLevels((prevState:OpenLevels) => {
return { ...prevState, [level]: !prevState[level] };
});
};
const hasChildren = trace.children && !!trace.children.length;
const progress = trace.duration / totalMsec * 100;
return (
<div
className={classNames({
"vm-nested-nav": true,
"vm-nested-nav_root": isRoot,
"vm-nested-nav_dark": isDarkTheme,
"vm-nested-nav_mobile": isMobile,
})}
>
<div
className="vm-nested-nav-header"
className={classNames({
"vm-nested-nav-header": true,
"vm-nested-nav-header_open": openLevels[trace.idValue],
})}
onClick={handleListClick(trace.idValue)}
>
{hasChildren && (
@ -84,7 +93,7 @@ const NestedNav: FC<RecursiveProps> = ({ trace, totalMsec }) => {
</div>
<div className="vm-nested-nav-header-bottom">
<div className="vm-nested-nav-header-bottom__duration">
{`duration: ${trace.duration} ms`}
{`duration: ${duration}`}
</div>
{(isExpanded || showFullMessage) && (
<Button
@ -97,15 +106,17 @@ const NestedNav: FC<RecursiveProps> = ({ trace, totalMsec }) => {
)}
</div>
</div>
{openLevels[trace.idValue] && <div>
{hasChildren && trace.children.map((trace) => (
<NestedNav
key={trace.duration}
trace={trace}
totalMsec={totalMsec}
/>
))}
</div>}
{openLevels[trace.idValue] && (
<div className="vm-nested-nav__childrens">
{hasChildren && trace.children.map((trace) => (
<NestedNav
key={trace.duration}
trace={trace}
totalMsec={totalMsec}
/>
))}
</div>
)}
</div>
);
};

View file

@ -1,29 +1,71 @@
@use "src/styles/variables" as *;
$color-base-nested-nav: $color-tropical-blue;
$color-base-nested-nav-dark: $color-background-body;
.vm-nested-nav {
margin-left: $padding-medium;
position: relative;
margin-left: $padding-global;
border-radius: $border-radius-small;
background-color: rgba($color-tropical-blue, 0.4);
&_dark &-header {
background-color: $color-base-nested-nav-dark;
&:after, &:before {
background-color: $color-base-nested-nav-dark;
}
&:hover {
box-shadow: rgba($color-white, 0.08) 0 0 0 1px;
}
}
&_mobile {
margin-left: $padding-small;
}
&_dark {
background-color: rgba($color-black, 0.1);
&_root > &-header {
&:before,
&:after {
display: none;
}
}
&-header {
position: relative;
display: grid;
grid-template-columns: auto 1fr;
gap: $padding-small;
padding: $padding-small;
border-radius: $border-radius-small;
transition: background-color 200ms ease-in-out;
transition: box-shadow 200ms ease-in-out;
cursor: pointer;
background-color: rgba($color-base-nested-nav, 0.4);
margin-bottom: $padding-small;
z-index: 2;
&:after {
content: "";
position: absolute;
top: calc(50% - 1px);
height: 2px;
width: $padding-small;
background-color: $color-base-nested-nav;
left: calc(-1 * $padding-small);
}
&:before {
content: "";
position: absolute;
bottom: 50%;
left: calc($padding-global / -2);
height: calc(50% + $padding-small);
width: 2px;
background-color: $color-base-nested-nav;
}
&:hover {
background-color: $color-hover-black;
box-shadow: rgba($color-black, 0.08) 0 0 0 1px;
}
&__icon {
@ -32,9 +74,11 @@
justify-content: center;
width: 20px;
transition: transform 200ms ease-in-out;
transform: rotate(-90deg);
color: $color-text-secondary;
&_open {
transform: rotate(180deg);
transform: rotate(0);
}
}
@ -72,4 +116,22 @@
}
}
}
&__childrens > .vm-nested-nav:not(:last-child) {
&:before {
content: "";
position: absolute;
top: 0;
left: calc($padding-global / -2);
height: 100%;
width: 2px;
background-color: $color-base-nested-nav;
}
}
&__childrens > .vm-nested-nav_dark:not(:last-child) {
&:before {
background-color: $color-base-nested-nav-dark;
}
}
}

View file

@ -89,6 +89,7 @@ const TracingsView: FC<TraceViewProps> = ({ traces, jsonEditor = false, onDelete
})}
>
<NestedNav
isRoot
trace={trace}
totalMsec={trace.duration}
/>

View file

@ -30,6 +30,10 @@ const shortDurations = supportedDurations.map(d => d.short);
export const roundToMilliseconds = (num: number): number => Math.round(num*1000)/1000;
export const humanizeSeconds = (num: number): string => {
return getDurationFromMilliseconds(dayjs.duration(num, "seconds").asMilliseconds());
};
export const roundStep = (step: number) => {
let result = roundToMilliseconds(step);
const integerStep = Math.round(step);
@ -46,8 +50,7 @@ export const roundStep = (step: number) => {
if (step < 1 && step > 0.01) {
result = Math.round(step * 40) / 40; // float to thousandths multiple of 5
}
const humanize = getDurationFromMilliseconds(dayjs.duration(result || 0.001, "seconds").asMilliseconds());
const humanize = humanizeSeconds(result || 0.001);
return humanize.replace(/\s/g, "");
};