Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 24 additions & 31 deletions src/components/Errors/NewErrorCard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,20 +95,17 @@ export const NewErrorCard = ({
})),
[affectedEndpoints]
);
const [selectedEndpoint, setSelectedEndpoint] = useState<Option | undefined>(
selectorOptions[0]
);
const [selectedEndpointKey, setSelectedEndpointKey] = useState<
string | undefined
>(selectorOptions[0] ? getEndpointKey(selectorOptions[0]) : undefined);

useEffect(() => {
if (
selectedEndpoint &&
!selectorOptions.find(
(x) => getEndpointKey(x) === getEndpointKey(selectedEndpoint)
)
) {
setSelectedEndpoint(selectorOptions[0]);
}
}, [selectorOptions, selectedEndpoint]);
const option = selectedEndpointKey
? selectorOptions.find((x) => getEndpointKey(x) === selectedEndpointKey)
: undefined;

setSelectedEndpointKey(option ? getEndpointKey(option) : undefined);
}, [selectorOptions, selectedEndpointKey]);

useEffect(() => {
if (
Expand Down Expand Up @@ -137,27 +134,19 @@ export const NewErrorCard = ({
onSourceLinkClick(id);
};

const handleAffectedEndpointsSelectorChange = (
selectedOption: Option | null
) => {
const handleAffectedEndpointsSelectorChange = (endpointKey: string) => {
sendUserActionTrackingEvent(
trackingEvents.ERROR_CARD_SELECTED_AFFECTED_ENDPOINT_CHANGED
);
const newValue = selectedOption
? selectorOptions.find(
(x) =>
x.serviceName === selectedOption.serviceName &&
x.spanCodeObjectId === selectedOption.spanCodeObjectId
)
: undefined;

setSelectedEndpoint(newValue);
setSelectedEndpointKey(endpointKey);
};

const handleAffectedEndpointLinkClick = (spanCodeObjectId: string) => {
sendUserActionTrackingEvent(
trackingEvents.ERROR_CARD_AFFECTED_ENDPOINT_LINK_CLICKED
);

changeScope({
span: {
spanCodeObjectId
Expand Down Expand Up @@ -207,9 +196,13 @@ export const NewErrorCard = ({

const isCritical = score.score > HIGH_SEVERITY_SCORE_THRESHOLD;

const selectorValue = selectedEndpoint
? getEndpointKey(selectedEndpoint)
: undefined;
const selectedOption = useMemo(
() =>
selectedEndpointKey
? selectorOptions.find((x) => getEndpointKey(x) === selectedEndpointKey)
: undefined,
[selectedEndpointKey, selectorOptions]
);

const toolbarActions = [
...(isPinEnabled
Expand All @@ -224,7 +217,7 @@ export const NewErrorCard = ({
/>
]
: []),
...(isOccurrenceChartEnabled && selectedEndpoint
...(isOccurrenceChartEnabled && selectedEndpointKey
? [
<NewIconButton
key={"toggle-occurrence-chart"}
Expand Down Expand Up @@ -282,12 +275,12 @@ export const NewErrorCard = ({
<AffectedEndpointsSelector
onChange={handleAffectedEndpointsSelectorChange}
onAssetLinkClick={handleAffectedEndpointLinkClick}
value={selectorValue}
value={selectedEndpointKey}
options={selectorOptions}
/>
</s.AffectedEndpointsContainer>
)}
{isOccurrenceChartEnabled && selectedEndpoint && (
{isOccurrenceChartEnabled && selectedOption && (
<>
<CSSTransition
in={isHistogramVisible}
Expand All @@ -303,8 +296,8 @@ export const NewErrorCard = ({
$transitionDuration={s.TRANSITION_DURATION}
>
<OccurrenceChart
service={selectedEndpoint.serviceName}
spanCodeObjectId={selectedEndpoint.spanCodeObjectId}
service={selectedOption.serviceName}
spanCodeObjectId={selectedOption.spanCodeObjectId}
errorId={id}
/>
</s.OccurrenceChartContainer>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useMemo, useState } from "react";
import { useEffect, useMemo, useState } from "react";
import { useConfigSelector } from "../../../../../../store/config/useConfigSelector";
import { getDurationString } from "../../../../../../utils/getDurationString";
import {
Expand All @@ -17,6 +17,12 @@ import { ContentContainer, Description, Details } from "../styles";
import * as s from "./styles";
import { SpaNPlusOneInsightCardProps } from "./types";

const getSelectorOption = (endpoint: NPlusOneEndpointInfo): Option => ({
route: endpoint.endpointInfo.route,
serviceName: endpoint.endpointInfo.serviceName,
spanCodeObjectId: endpoint.endpointInfo.entrySpanCodeObjectId
});

export const SpaNPlusOneInsightCard = ({
insight,
onAssetLinkClick,
Expand All @@ -30,15 +36,27 @@ export const SpaNPlusOneInsightCard = ({
viewMode
}: SpaNPlusOneInsightCardProps) => {
const endpoints = useMemo(() => insight.endpoints ?? [], [insight.endpoints]);
const selectorOptions = useMemo(
() => endpoints.map(getSelectorOption),
[endpoints]
);
const endpointWithMaxDuration = endpoints.reduce(
(acc, cur) => (acc.duration.raw >= cur.duration.raw ? acc : cur),
endpoints[0]
);
const maxDurationString = getDurationString(endpointWithMaxDuration.duration);
const { isJaegerEnabled } = useConfigSelector();
const [selectedEndpoint, setSelectedEndpoint] = useState<
NPlusOneEndpointInfo | undefined
>(endpoints[0]);
const [selectedEndpointKey, setSelectedEndpointKey] = useState<
string | undefined
>(selectorOptions[0] ? getEndpointKey(selectorOptions[0]) : undefined);

useEffect(() => {
const option = selectedEndpointKey
? selectorOptions.find((x) => getEndpointKey(x) === selectedEndpointKey)
: undefined;

setSelectedEndpointKey(option ? getEndpointKey(option) : undefined);
}, [selectorOptions, selectedEndpointKey]);

const handleSpanLinkClick = (spanCodeObjectId?: string) => {
if (spanCodeObjectId) {
Expand All @@ -63,43 +81,18 @@ export const SpaNPlusOneInsightCard = ({
}
};

const handleAffectedEndpointsSelectorChange = (option: Option | null) => {
const newValue = option
? endpoints.find(
(x) =>
x.endpointInfo.serviceName === option.serviceName &&
x.endpointInfo.entrySpanCodeObjectId === option.spanCodeObjectId
)
: undefined;

setSelectedEndpoint(newValue);
const handleAffectedEndpointsSelectorChange = (endpointKey: string) => {
setSelectedEndpointKey(endpointKey);
};

const selectorOptions = useMemo(
() =>
endpoints.map((x) => ({
route: x.endpointInfo.route,
serviceName: x.endpointInfo.serviceName,
spanCodeObjectId: x.endpointInfo.entrySpanCodeObjectId
})),
[endpoints]
);

const selectedOption = useMemo(
const selectedEndpoint = useMemo(
() =>
selectedEndpoint &&
selectorOptions.find(
(x) =>
x.serviceName === selectedEndpoint.endpointInfo.serviceName &&
x.spanCodeObjectId ===
selectedEndpoint.endpointInfo.entrySpanCodeObjectId
),
[selectedEndpoint, selectorOptions]
);

const selectorValue = useMemo(
() => (selectedOption ? getEndpointKey(selectedOption) : undefined),
[selectedOption]
selectedEndpointKey
? endpoints.find(
(x) => getEndpointKey(x.endpointInfo) === selectedEndpointKey
)
: undefined,
[selectedEndpointKey, endpoints]
);

return (
Expand All @@ -113,7 +106,7 @@ export const SpaNPlusOneInsightCard = ({
</Description>
<s.SelectContainer>
<AffectedEndpointsSelector
value={selectorValue}
value={selectedEndpointKey}
onChange={handleAffectedEndpointsSelectorChange}
options={selectorOptions}
onAssetLinkClick={handleSpanLinkClick}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useMemo, useState } from "react";
import { useEffect, useMemo, useState } from "react";
import { useConfigSelector } from "../../../../../../store/config/useConfigSelector";
import { isNull } from "../../../../../../typeGuards/isNull";
import { getDurationString } from "../../../../../../utils/getDurationString";
Expand All @@ -19,6 +19,12 @@ import { ContentContainer, Description, Details } from "../styles";
import * as s from "./styles";
import { SpanEndpointBottleneckInsightCardProps } from "./types";

const getSelectorOption = (endpoint: BottleneckEndpointInfo): Option => ({
route: trimEndpointScheme(endpoint.endpointInfo.route),
serviceName: endpoint.endpointInfo.serviceName,
spanCodeObjectId: endpoint.endpointInfo.spanCodeObjectId
});

export const SpanEndpointBottleneckInsightCard = ({
insight,
onJiraTicketCreate,
Expand All @@ -36,6 +42,11 @@ export const SpanEndpointBottleneckInsightCard = ({
() => insight.slowEndpoints ?? [],
[insight.slowEndpoints]
);
const selectorOptions: Option[] = useMemo(
() => slowEndpoints.map(getSelectorOption),
[slowEndpoints]
);

const endpointWithMaxDuration =
slowEndpoints.length > 0
? slowEndpoints.reduce(
Expand All @@ -51,9 +62,17 @@ export const SpanEndpointBottleneckInsightCard = ({
? getDurationString(endpointWithMaxDuration.avgDurationWhenBeingBottleneck)
: undefined;

const [selectedEndpoint, setSelectedEndpoint] = useState<
BottleneckEndpointInfo | undefined
>(slowEndpoints[0]);
const [selectedEndpointKey, setSelectedEndpointKey] = useState<
string | undefined
>(selectorOptions[0] ? getEndpointKey(selectorOptions[0]) : undefined);

useEffect(() => {
const newOption = selectedEndpointKey
? selectorOptions.find((x) => getEndpointKey(x) === selectedEndpointKey)
: undefined;

setSelectedEndpointKey(newOption ? getEndpointKey(newOption) : undefined);
}, [selectorOptions, selectedEndpointKey]);

const handleSpanLinkClick = (spanCodeObjectId?: string) => {
if (spanCodeObjectId) {
Expand All @@ -78,45 +97,18 @@ export const SpanEndpointBottleneckInsightCard = ({
onTraceButtonClick(trace, insightType, spanCodeObjectId);
};

const handleAffectedEndpointsSelectorChange = (
selectedOption: Option | null
) => {
const newValue = selectedOption
? slowEndpoints.find(
(x) =>
x.endpointInfo.spanCodeObjectId ===
selectedOption.spanCodeObjectId &&
x.endpointInfo.serviceName === selectedOption.serviceName
)
: undefined;

setSelectedEndpoint(newValue);
const handleAffectedEndpointsSelectorChange = (endpointKey: string) => {
setSelectedEndpointKey(endpointKey);
};

const selectorOptions: Option[] = useMemo(
const selectedEndpoint = useMemo(
() =>
slowEndpoints.map((x) => ({
route: trimEndpointScheme(x.endpointInfo.route),
serviceName: x.endpointInfo.serviceName,
spanCodeObjectId: x.endpointInfo.spanCodeObjectId
})),
[slowEndpoints]
);

const selectedOption = useMemo(
() =>
selectedEndpoint &&
selectorOptions.find(
(x) =>
x.serviceName === selectedEndpoint.endpointInfo.serviceName &&
x.spanCodeObjectId === selectedEndpoint.endpointInfo.spanCodeObjectId
),
[selectedEndpoint, selectorOptions]
);

const selectorValue = useMemo(
() => (selectedOption ? getEndpointKey(selectedOption) : undefined),
[selectedOption]
selectedEndpointKey
? slowEndpoints.find(
(x) => getEndpointKey(x.endpointInfo) === selectedEndpointKey
)
: undefined,
[selectedEndpointKey, slowEndpoints]
);

return (
Expand All @@ -137,7 +129,7 @@ export const SpanEndpointBottleneckInsightCard = ({
<AffectedEndpointsSelector
onChange={handleAffectedEndpointsSelectorChange}
onAssetLinkClick={handleSpanLinkClick}
value={selectorValue}
value={selectedEndpointKey}
options={selectorOptions}
isDisabled={selectorOptions.length === 0}
/>
Expand Down
7 changes: 2 additions & 5 deletions src/components/common/AffectedEndpointsSelector/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,8 @@ export const AffectedEndpointsSelector = ({
}
};

const handleSelectChange = (selectedOption: string) => {
const selected =
options.find((x) => getEndpointKey(x) === selectedOption) ?? null;

onChange(selected);
const handleSelectChange = (value: string) => {
onChange(value);
};

return (
Expand Down
2 changes: 1 addition & 1 deletion src/components/common/AffectedEndpointsSelector/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export interface ContainerProps {
export interface AffectedEndpointsSelectorProps {
value?: string;
options: Option[];
onChange: (selected: Option | null) => void;
onChange: (value: string) => void;
onAssetLinkClick: (spanCodeObjectId: string) => void;
isDisabled?: boolean;
}
Expand Down
Loading