props.manager.registerSpanBarRef(r, props.node_space!, props.virtualized_index)
}
className="TraceBar"
style={{
transform: `matrix(${spanTransform.join(',')})`,
backgroundColor: props.color,
}}
/>
props.manager.registerSpanBarTextRef(
r,
duration,
props.node_space!,
props.virtualized_index
)
}
className="TraceBarDuration"
style={{
color: inside ? 'white' : '',
transform: `translate(${textTransform ?? 0}px, 0)`,
}}
>
{duration}
);
}
interface InvisibleTraceBarProps {
children: React.ReactNode;
manager: VirtualizedViewManager;
node_space: [number, number] | null;
virtualizedIndex: number;
}
function InvisibleTraceBar(props: InvisibleTraceBarProps) {
if (!props.node_space || !props.children) {
return null;
}
const transform = `translateX(${props.manager.computeTransformXFromTimestamp(props.node_space[0])}px)`;
return (
props.manager.registerInvisibleBarRef(
r,
props.node_space!,
props.virtualizedIndex
)
}
className="TraceBar Invisible"
style={{
transform,
}}
onDoubleClick={e => {
e.stopPropagation();
props.manager.onZoomIntoSpace(props.node_space!);
}}
>
{props.children}
);
}
interface AutogroupedTraceBarProps {
color: string;
entire_space: [number, number] | null;
manager: VirtualizedViewManager;
node_spaces: [number, number][];
virtualized_index: number;
duration?: number;
}
function AutogroupedTraceBar(props: AutogroupedTraceBarProps) {
if (props.node_spaces && props.node_spaces.length <= 1) {
return (
);
}
if (!props.node_spaces || !props.entire_space) {
return null;
}
const duration = getDuration(props.entire_space[1] / 1000, 2, true);
const spanTransform = props.manager.computeSpanCSSMatrixTransform(props.entire_space);
const [inside, textTransform] = props.manager.computeSpanTextPlacement(
props.entire_space,
duration
);
return (
props.manager.registerSpanBarRef(
r,
props.entire_space!,
props.virtualized_index
)
}
className="TraceBar Invisible"
style={{
transform: `matrix(${spanTransform.join(',')})`,
backgroundColor: props.color,
}}
>
{props.node_spaces.map((node_space, i) => {
const width = node_space[1] / props.entire_space![1];
const left = (node_space[0] - props.entire_space![0]) / props.entire_space![1];
return (
);
})}
props.manager.registerSpanBarTextRef(
r,
duration,
props.entire_space!,
props.virtualized_index
)
}
className="TraceBarDuration"
style={{
color: inside ? 'white' : '',
transform: `translate(${textTransform ?? 0}px, 0)`,
}}
>
{duration}
);
}
/**
* This is a wrapper around the Trace component to apply styles
* to the trace tree. It exists because we _do not_ want to trigger
* emotion's css parsing logic as it is very slow and will cause
* the scrolling to flicker.
*/
const TraceStylingWrapper = styled('div')`
flex-grow: 1;
width: 100%;
margin: auto;
overflow: hidden;
position: relative;
box-shadow: 0 0 0 1px ${p => p.theme.border};
border-radius: 4px;
padding-top: 22px;
&.WithIndicators {
padding-top: 44px;
&:before {
height: 44px;
}
.TraceIndicator.Timeline {
.TraceIndicatorLabel {
top: 26px;
}
.TraceIndicatorLine {
top: 30px;
}
}
}
&:before {
content: '';
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 22px;
background-color: ${p => p.theme.backgroundSecondary};
border-bottom: 1px solid ${p => p.theme.border};
}
&.Loading {
.TraceRow {
.TraceLeftColumnInner {
width: 100%;
}
}
.TraceRightColumn {
background-color: transparent !important;
}
.TraceDivider {
pointer-events: none;
}
}
.TraceDivider {
position: absolute;
height: 100%;
background-color: transparent;
top: 0;
cursor: col-resize;
z-index: 10;
&:before {
content: '';
position: absolute;
width: 1px;
height: 100%;
background-color: ${p => p.theme.border};
left: 50%;
}
&:hover {
&:before {
background-color: ${p => p.theme.purple300};
}
}
}
.TraceIndicatorContainer {
overflow: hidden;
width: 100%;
height: 100%;
position: absolute;
right: 0;
top: 0;
}
.TraceIndicator {
z-index: 1;
width: 3px;
height: 100%;
top: 0;
position: absolute;
.TraceIndicatorLabel {
min-width: 34px;
text-align: center;
position: absolute;
font-size: ${p => p.theme.fontSizeExtraSmall};
font-weight: bold;
color: ${p => p.theme.textColor};
background-color: ${p => p.theme.background};
border-radius: ${p => p.theme.borderRadius};
border: 1px solid ${p => p.theme.border};
padding: 2px;
display: inline-block;
line-height: 1;
margin-top: 2px;
white-space: nowrap;
}
.TraceIndicatorLine {
width: 1px;
height: 100%;
top: 20px;
position: absolute;
left: 50%;
transform: translateX(-2px);
background: repeating-linear-gradient(
to bottom,
transparent 0 4px,
${p => p.theme.textColor} 4px 8px
)
80%/2px 100% no-repeat;
}
&.Timeline {
opacity: 1;
z-index: 1;
pointer-events: none;
.TraceIndicatorLabel {
font-weight: normal;
min-width: 0;
top: 2px;
width: auto;
border: none;
background-color: transparent;
color: ${p => p.theme.subText};
}
.TraceIndicatorLine {
background: ${p => p.theme.translucentGray100};
top: 4px;
}
}
}
.TraceRow {
display: flex;
align-items: center;
position: absolute;
height: 24px;
width: 100%;
transition: none;
font-size: ${p => p.theme.fontSizeSmall};
.Errored {
color: ${p => p.theme.error};
}
.TraceError {
position: absolute;
transform: translate(-50%, 0);
background: ${p => p.theme.background};
width: 16px !important;
height: 16px !important;
background-color: ${p => p.theme.error};
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
svg {
fill: ${p => p.theme.white};
}
}
.TraceRightColumn.Odd {
background-color: ${p => p.theme.backgroundSecondary};
}
&:hover {
background-color: ${p => p.theme.backgroundSecondary};
}
&.Highlight,
&:focus {
outline: none;
background-color: ${p => p.theme.backgroundTertiary};
.TraceRightColumn.Odd {
background-color: transparent !important;
}
}
&:focus {
box-shadow: inset 0 0 0 1px ${p => p.theme.blue300} !important;
.TraceLeftColumn {
box-shadow: inset 0px 0 0px 1px ${p => p.theme.blue300} !important;
}
}
&.Highlight {
box-shadow: inset 0 0 0 1px ${p => p.theme.blue200} !important;
.TraceLeftColumn {
box-shadow: inset 0px 0 0px 1px ${p => p.theme.blue200} !important;
}
}
&.SearchResult {
background-color: ${p => p.theme.yellow100};
.TraceRightColumn {
background-color: transparent;
}
}
&.Autogrouped {
color: ${p => p.theme.blue300};
.TraceDescription {
font-weight: bold;
}
.TraceChildrenCountWrapper {
button {
color: ${p => p.theme.white};
background-color: ${p => p.theme.blue300};
}
}
}
}
.TraceLeftColumn {
height: 100%;
white-space: nowrap;
display: flex;
align-items: center;
overflow: hidden;
will-change: width;
box-shadow: inset 1px 0 0px 0px transparent;
.TraceLeftColumnInner {
height: 100%;
white-space: nowrap;
display: flex;
align-items: center;
will-change: transform;
transform-origin: left center;
img {
width: 16px;
height: 16px;
}
}
}
.TraceRightColumn {
height: 100%;
overflow: hidden;
position: relative;
display: flex;
align-items: center;
will-change: width;
z-index: 1;
&:hover {
.TraceArrow.Visible {
opacity: 1;
transition: 300ms 300ms ease-out;
pointer-events: auto;
}
}
}
.TraceBar {
position: absolute;
height: 64%;
width: 100%;
background-color: black;
transform-origin: left center;
&.Invisible {
background-color: transparent !important;
> div {
height: 100%;
}
}
}
.TraceArrow {
position: absolute;
pointer-events: none;
top: 0;
width: 14px;
height: 24px;
opacity: 0;
background-color: transparent;
border: none;
transition: 60ms ease-out;
font-size: ${p => p.theme.fontSizeMedium};
color: ${p => p.theme.subText};
padding: 0 2px;
display: flex;
align-items: center;
&.Left {
left: 0;
}
&.Right {
right: 0;
transform: rotate(180deg);
}
}
.TraceBarDuration {
display: inline-block;
transform-origin: left center;
font-size: ${p => p.theme.fontSizeExtraSmall};
color: ${p => p.theme.gray300};
white-space: nowrap;
font-variant-numeric: tabular-nums;
position: absolute;
transition: color 0.1s ease-in-out;
}
.TraceChildrenCount {
height: 16px;
white-space: nowrap;
min-width: 30px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 99px;
padding: 0px 4px;
transition: all 0.15s ease-in-out;
background: ${p => p.theme.background};
border: 2px solid ${p => p.theme.border};
line-height: 0;
z-index: 1;
font-size: 10px;
box-shadow: ${p => p.theme.dropShadowLight};
margin-right: 8px;
&.Errored {
border: 2px solid ${p => p.theme.error};
}
.TraceChildrenCountContent {
+ .TraceChildrenCountAction {
margin-left: 2px;
}
}
.TraceChildrenCountAction {
position: relative;
display: flex;
align-items: center;
justify-content: center;
}
.TraceActionsLoadingIndicator {
margin: 0;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: ${p => p.theme.background};
animation: show 0.1s ease-in-out forwards;
@keyframes show {
from {
opacity: 0;
transform: translate(-50%, -50%) scale(0.86);
}
to {
opacity: 1;
transform: translate(-50%, -50%) scale(1);
}
}
.loading-indicator {
border-width: 2px;
}
.loading-message {
display: none;
}
}
svg {
width: 7px;
transition: none;
}
}
.TraceChildrenCountWrapper {
display: flex;
justify-content: flex-end;
align-items: center;
min-width: 44px;
height: 100%;
position: relative;
button {
transition: none;
}
&.Orphaned {
.TraceVerticalConnector,
.TraceVerticalLastChildConnector,
.TraceExpandedVerticalConnector {
border-left: 2px dashed ${p => p.theme.border};
}
&::before {
border-bottom: 2px dashed ${p => p.theme.border};
}
}
&.Root {
&:before,
.TraceVerticalLastChildConnector {
visibility: hidden;
}
}
&::before {
content: '';
display: block;
width: 50%;
height: 2px;
border-bottom: 2px solid ${p => p.theme.border};
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
}
&::after {
content: '';
background-color: ${p => p.theme.border};
border-radius: 50%;
height: 6px;
width: 6px;
position: absolute;
left: 50%;
top: 50%;
transform: translateY(-50%);
}
}
.TraceVerticalConnector {
position: absolute;
left: 0;
top: 0;
bottom: 0;
height: 100%;
width: 2px;
border-left: 2px solid ${p => p.theme.border};
&.Orphaned {
border-left: 2px dashed ${p => p.theme.border};
}
}
.TraceVerticalLastChildConnector {
position: absolute;
left: 0;
top: 0;
bottom: 0;
height: 50%;
width: 2px;
border-left: 2px solid ${p => p.theme.border};
border-bottom-left-radius: 4px;
}
.TraceExpandedVerticalConnector {
position: absolute;
bottom: 0;
height: 50%;
left: 50%;
width: 2px;
border-left: 2px solid ${p => p.theme.border};
}
.TraceOperation {
margin-left: 4px;
text-overflow: ellipsis;
white-space: nowrap;
font-weight: bold;
}
.TraceEmDash {
margin-left: 4px;
margin-right: 4px;
}
.TraceDescription {
white-space: nowrap;
}
`;
const LoadingContainer = styled('div')`
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
position: absolute;
height: auto;
font-size: ${p => p.theme.fontSizeMedium};
color: ${p => p.theme.gray300};
z-index: 30;
padding: 24px;
background-color: ${p => p.theme.background};
border-radius: ${p => p.theme.borderRadius};
border: 1px solid ${p => p.theme.border};
`;
function TraceLoading() {
return (
{t('Assembling the trace')}
);
}
const NoMarginIndicator = styled(LoadingIndicator)`
margin: 0;
`;