mirror of
https://github.com/hyperdxio/hyperdx
synced 2026-04-21 13:37:15 +00:00
design: Make service map drill-down links more obvious (#1738)
# Summary The buttons within the service map tooltips were hard to recognize as buttons/links. I've added an icon and give them a hover state. ## Before <img width="277" height="124" alt="Screenshot 2026-02-13 at 2 28 14 PM" src="https://github.com/user-attachments/assets/256b0b7d-b6eb-44e6-8a69-c0bf2b15db17" /> ## After <img width="202" height="197" alt="Screenshot 2026-02-13 at 2 27 26 PM" src="https://github.com/user-attachments/assets/27e26ff9-b644-4d14-8217-cf4e7fd53d84" />
This commit is contained in:
parent
35494dc032
commit
69f0b487fb
3 changed files with 62 additions and 50 deletions
5
.changeset/kind-peas-kneel.md
Normal file
5
.changeset/kind-peas-kneel.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
"@hyperdx/app": patch
|
||||
---
|
||||
|
||||
design: Make service map drill-down links more obvious
|
||||
|
|
@ -6,15 +6,10 @@
|
|||
}
|
||||
|
||||
.toolbar {
|
||||
padding: 4px 8px;
|
||||
padding: 4px;
|
||||
border-radius: 4px;
|
||||
background-color: #f0f0f0;
|
||||
border: 1px solid #ccc;
|
||||
color: #111;
|
||||
|
||||
.linkButton {
|
||||
font-size: small;
|
||||
}
|
||||
background-color: var(--color-bg-header);
|
||||
border: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
.serviceNode {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import { useCallback } from 'react';
|
||||
import SqlString from 'sqlstring';
|
||||
import { TSource } from '@hyperdx/common-utils/dist/types';
|
||||
import { UnstyledButton } from '@mantine/core';
|
||||
import { Button, Group, Stack, UnstyledButton } from '@mantine/core';
|
||||
import { IconSearch } from '@tabler/icons-react';
|
||||
|
||||
import { formatApproximateNumber, navigateToTraceSearch } from './utils';
|
||||
|
||||
|
|
@ -21,53 +23,63 @@ export default function ServiceMapTooltip({
|
|||
serviceName: string;
|
||||
isSingleTrace?: boolean;
|
||||
}) {
|
||||
const requestText = `${isSingleTrace ? totalRequests : formatApproximateNumber(totalRequests)} request${
|
||||
totalRequests !== 1 ? 's' : ''
|
||||
}`;
|
||||
const errorsText = `${errorPercentage.toFixed(2)}% errors`;
|
||||
|
||||
const handleRequestsClick = useCallback(() => {
|
||||
navigateToTraceSearch({
|
||||
dateRange,
|
||||
source,
|
||||
where: SqlString.format("? = ? AND ? IN ('Server', 'Consumer')", [
|
||||
SqlString.raw(source.serviceNameExpression ?? 'ServiceName'),
|
||||
serviceName,
|
||||
SqlString.raw(source.spanKindExpression ?? 'SpanKind'),
|
||||
]),
|
||||
});
|
||||
}, [dateRange, source, serviceName]);
|
||||
|
||||
const handleErrorsClick = useCallback(() => {
|
||||
navigateToTraceSearch({
|
||||
dateRange,
|
||||
source,
|
||||
where: SqlString.format(
|
||||
"? = ? AND ? IN ('Server', 'Consumer') AND ? = 'Error'",
|
||||
[
|
||||
SqlString.raw(source.serviceNameExpression ?? 'ServiceName'),
|
||||
serviceName,
|
||||
SqlString.raw(source.spanKindExpression ?? 'SpanKind'),
|
||||
SqlString.raw(source.statusCodeExpression ?? 'StatusCode'),
|
||||
],
|
||||
),
|
||||
});
|
||||
}, [dateRange, source, serviceName]);
|
||||
|
||||
return (
|
||||
<div className={styles.toolbar}>
|
||||
<UnstyledButton
|
||||
onClick={() =>
|
||||
navigateToTraceSearch({
|
||||
dateRange,
|
||||
source,
|
||||
where: SqlString.format("? = ? AND ? IN ('Server', 'Consumer')", [
|
||||
SqlString.raw(source.serviceNameExpression ?? 'ServiceName'),
|
||||
serviceName,
|
||||
SqlString.raw(source.spanKindExpression ?? 'SpanKind'),
|
||||
]),
|
||||
})
|
||||
}
|
||||
className={styles.linkButton}
|
||||
<Stack className={styles.toolbar} gap={0}>
|
||||
<Button
|
||||
onClick={handleRequestsClick}
|
||||
variant="subtle"
|
||||
size="xs"
|
||||
color="var(--color-text)"
|
||||
rightSection={<IconSearch size={16} />}
|
||||
>
|
||||
{isSingleTrace ? totalRequests : formatApproximateNumber(totalRequests)}{' '}
|
||||
request
|
||||
{totalRequests !== 1 ? 's' : ''}
|
||||
</UnstyledButton>
|
||||
{requestText}
|
||||
</Button>
|
||||
{errorPercentage > 0 ? (
|
||||
<>
|
||||
{', '}
|
||||
<UnstyledButton
|
||||
onClick={() =>
|
||||
navigateToTraceSearch({
|
||||
dateRange,
|
||||
source,
|
||||
where: SqlString.format(
|
||||
"? = ? AND ? IN ('Server', 'Consumer') AND ? = 'Error'",
|
||||
[
|
||||
SqlString.raw(
|
||||
source.serviceNameExpression ?? 'ServiceName',
|
||||
),
|
||||
serviceName,
|
||||
SqlString.raw(source.spanKindExpression ?? 'SpanKind'),
|
||||
SqlString.raw(source.statusCodeExpression ?? 'StatusCode'),
|
||||
],
|
||||
),
|
||||
})
|
||||
}
|
||||
className={styles.linkButton}
|
||||
<Button
|
||||
onClick={handleErrorsClick}
|
||||
variant="subtle"
|
||||
size="xs"
|
||||
color="var(--color-text-danger)"
|
||||
rightSection={<IconSearch size={16} />}
|
||||
>
|
||||
{errorPercentage.toFixed(2)}% error
|
||||
</UnstyledButton>
|
||||
{errorsText}
|
||||
</Button>
|
||||
</>
|
||||
) : null}
|
||||
</div>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue