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
2 changes: 1 addition & 1 deletion dependencies.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"jetBrainsPluginVersion": "2.0.411",
"visualStudioExtensionVersion": "1.2.4",
"jaegerUIVersion": "1.29.1-digma.1.1.2",
"jaegerUIVersion": "1.29.1-digma.1.2.0",
"jaegerVersion": "1.45.0"
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,46 +19,26 @@ import {
setIssuesInsightInfoToOpenTicket
} from "../../../../../../redux/slices/repositorySlice";
import { isUndefined } from "../../../../../../typeGuards/isUndefined";
import { InsightType } from "../../../../../../types";
import type { ChangeScopePayload } from "../../../../../../utils/actions/changeScope";
import { sendUserActionTrackingEvent } from "../../../../../../utils/actions/sendUserActionTrackingEvent";
import { EyeIcon } from "../../../../../common/icons/16px/EyeIcon";
import { Pagination } from "../../../../../common/Pagination";
import { NewButton } from "../../../../../common/v3/NewButton";
import { EmptyState } from "../../../../../Insights/EmptyState";
import { getInsightToShowJiraHint } from "../../../../../Insights/InsightsCatalog/InsightsPage";
import { EmptyState as InsightsPageEmptyState } from "../../../../../Insights/InsightsCatalog/InsightsPage/EmptyState";
import { InsightCardRenderer } from "../../../../../Insights/InsightsCatalog/InsightsPage/InsightCardRenderer";
import { actions } from "../../../../../Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/common/InsightCard/hooks/useDismissal";
import { ViewMode } from "../../../../../Insights/InsightsCatalog/types";
import { InsightTicketRenderer } from "../../../../../Insights/InsightTicketRenderer";
import {
type CodeObjectInsight,
type GenericCodeObjectInsight
} from "../../../../../Insights/types";
import { type GenericCodeObjectInsight } from "../../../../../Insights/types";
import { trackingEvents } from "../../../../tracking";
import { SuggestionBar } from "../SuggestionBar";
import * as s from "./styles";
import type { IssuesProps } from "./types";

const PAGE_SIZE = 10;

const getInsightToShowJiraHint = (insights: CodeObjectInsight[]): number => {
const insightsWithJiraButton = [
InsightType.EndpointSpanNPlusOne,
InsightType.SpaNPlusOne,
InsightType.SpanEndpointBottleneck,
InsightType.EndpointBottleneck,
InsightType.SpanQueryOptimization,
InsightType.EndpointHighNumberOfQueries,
InsightType.EndpointQueryOptimizationV2,
InsightType.SpanScaling
];

return insights.findIndex((insight) =>
insightsWithJiraButton.includes(insight.type)
);
};

export const Issues = ({
isTransitioning,
query,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const DiscoveredCard = ({ options, title }: DiscoveredCardProps) => {
<CardOption
key={option.title}
{...option}
isActive={selected == option.title}
isActive={selected === option.title}
/>
))}
</s.Row>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ export const FlowStack = ({ data }: FlowStackProps) => {
: frames;

const spanGroups = visibleFrames.reduce((acc, frame, i) => {
if (i == 0 || frame.spanName !== frames[i - 1].spanName) {
if (i === 0 || frame.spanName !== frames[i - 1].spanName) {
acc.push([frame]);
} else {
acc[acc.length - 1].push(frame);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
isEndpointChattyApiV2Highlight,
isEndpointHighNumberOfQueriesHighlight,
isEndpointQueryOptimizationV2Highlight,
isEndpointScalingHighlight,
isEndpointSessionInViewHighlight,
isEndpointSlowdownSourceHighlight,
isEndpointSpanNPlusOneHighlight,
Expand All @@ -17,6 +18,7 @@ import { EndpointBottleneckHighlightCard } from "../highlightCards/EndpointBottl
import { EndpointChattyApiV2HighlightCard } from "../highlightCards/EndpointChattyApiV2HighlightCard";
import { EndpointHighNumberOfQueriesHighlightCard } from "../highlightCards/EndpointHighNumberOfQueriesHighlightCard";
import { EndpointQueryOptimizationV2HighlightCard } from "../highlightCards/EndpointQueryOptimizationV2HighlightCard";
import { EndpointScalingHighlightCard } from "../highlightCards/EndpointScalingHighlightCard";
import { EndpointSessionInViewHighlightCard } from "../highlightCards/EndpointSessionInViewHighlightCard";
import { EndpointSlowdownSourceHighlightCard } from "../highlightCards/EndpointSlowdownSourceHighlightCard";
import { EndpointSpanNPlusOneHighlightCard } from "../highlightCards/EndpointSpanNPlusOneHighlightCard";
Expand Down Expand Up @@ -82,4 +84,8 @@ export const HighlightCardRenderer = ({
if (isSpanPerformanceAnomalyHighlight(highlight)) {
return <SpanPerformanceAnomalyHighlightCard data={highlight} />;
}

if (isEndpointScalingHighlight(highlight)) {
return <EndpointScalingHighlightCard data={highlight} />;
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import type { Meta, StoryObj } from "@storybook/react";
import { EndpointScalingHighlightCard } from ".";
import { mockedEndpointScalingHighlightData } from "./mockData";

// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction
const meta: Meta<typeof EndpointScalingHighlightCard> = {
title: "Highlights/TopIssues/highlightCards/EndpointScalingHighlightCard",
component: EndpointScalingHighlightCard,
parameters: {
// More on how to position stories at: https://storybook.js.org/docs/react/configure/story-layout
layout: "fullscreen"
}
};

export default meta;

type Story = StoryObj<typeof meta>;

// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args

export const Default: Story = {
args: {
data: mockedEndpointScalingHighlightData
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import type { Row } from "@tanstack/react-table";
import { createColumnHelper } from "@tanstack/react-table";
import type {
EndpointScalingMetrics,
EnvironmentData
} from "../../../../../redux/services/types";
import { useConfigSelector } from "../../../../../store/config/useConfigSelector";
import { ScopeChangeEvent } from "../../../../../types";
import { sendUserActionTrackingEvent } from "../../../../../utils/actions/sendUserActionTrackingEvent";
import { Table } from "../../../common/Table";
import { TableText } from "../../../common/TableText";
import { handleEnvironmentTableRowClick } from "../../../handleEnvironmentTableRowClick";
import { trackingEvents } from "../../../tracking";
import { HighlightCard } from "../../common/HighlightCard";
import { addEnvironmentColumns } from "../addEnvironmentColumns";
import type { EndpointScalingHighlightCardProps } from "./types";

export const EndpointScalingHighlightCard = ({
data
}: EndpointScalingHighlightCardProps) => {
const { scope, environments } = useConfigSelector();

const columnHelper =
createColumnHelper<EnvironmentData<EndpointScalingMetrics>>();

const metricsColumns = [
columnHelper.accessor(
(x) => x.metrics.find((x) => x.id === "IncreasePercentage"),
{
header: "Increased by",
cell: (info) => {
const metric = info.getValue();
const value = metric ? `${String(metric.value)}%` : "";
return metric ? <TableText title={value}>{value}</TableText> : null;
}
}
)
];

const columns = addEnvironmentColumns(columnHelper, metricsColumns);

const handleTableRowClick = (
row: Row<EnvironmentData<EndpointScalingMetrics>>
) => {
sendUserActionTrackingEvent(
trackingEvents.TOP_ISSUES_CARD_TABLE_ROW_CLICKED,
{
insightType: data.insightType
}
);
handleEnvironmentTableRowClick(
scope,
environments,
row.original.environmentId,
ScopeChangeEvent.HighlightsTopIssuesCardItemClicked
);
};

return (
<HighlightCard
highlight={data}
content={
<Table<EnvironmentData<EndpointScalingMetrics>>
columns={columns}
data={data.environments}
onRowClick={handleTableRowClick}
/>
}
/>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import type {
EndpointScalingMetrics,
HighlightData
} from "../../../../../redux/services/types";
import { InsightType } from "../../../../../types";
import { InsightStatus } from "../../../../Insights/types";

export const mockedEndpointScalingMetrics: EndpointScalingMetrics = [
{
id: "IncreasePercentage",
value: 50
}
];

export const mockedEndpointScalingHighlightData: HighlightData<EndpointScalingMetrics> =
{
insightType: InsightType.EndpointScaling,
asset: {
name: "spanName",
displayName: "displayName",
instrumentationLibrary: "instrumentationLibrary",
spanCodeObjectId: "spanCodeObjectId",
methodCodeObjectId: "methodCodeObjectId",
kind: "kind"
},
environments: [
{
environmentId: "1",
environmentName: "Dev",
insightStatus: InsightStatus.Active,
insightCriticality: 0.8,
metrics: mockedEndpointScalingMetrics
},
{
environmentId: "2",
environmentName: "Staging",
insightStatus: InsightStatus.Active,
insightCriticality: 0.8,
metrics: mockedEndpointScalingMetrics
},
{
environmentId: "3",
environmentName: "Production",
insightStatus: InsightStatus.Active,
insightCriticality: 0.8,
metrics: mockedEndpointScalingMetrics
},
{
environmentId: "4",
environmentName: "Env1",
insightStatus: InsightStatus.Active,
insightCriticality: 0.8,
metrics: mockedEndpointScalingMetrics
},
{
environmentId: "5",
environmentName: "Env2",
insightStatus: InsightStatus.Active,
insightCriticality: 0.8,
metrics: mockedEndpointScalingMetrics
},
{
environmentId: "6",
environmentName: "Env3",
insightStatus: InsightStatus.Active,
insightCriticality: 0.8,
metrics: mockedEndpointScalingMetrics
}
]
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import type {
EndpointScalingMetrics,
HighlightData
} from "../../../../../redux/services/types";

export interface EndpointScalingHighlightCardProps {
data: HighlightData<EndpointScalingMetrics>;
}
30 changes: 29 additions & 1 deletion src/components/Insights/InsightTicketRenderer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
isEndpointBottleneckInsight,
isEndpointHighNumberOfQueriesInsight,
isEndpointQueryOptimizationV2Insight,
isEndpointScalingInsight,
isEndpointSpanNPlusOneInsight,
isSpanEndpointBottleneckInsight,
isSpanNPlusOneInsight,
Expand All @@ -13,6 +14,7 @@ import type {
EndpointBottleneckInsight,
EndpointHighNumberOfQueriesInsight,
EndpointQueryOptimizationV2Insight,
EndpointScalingInsight,
EndpointSpanNPlusOneInsight,
InsightTicketInfo,
SpanEndpointBottleneckInsight,
Expand All @@ -24,6 +26,8 @@ import type {
import { EndpointBottleneckInsightTicket } from "./insightTickets/EndpointBottleneckInsightTicket";
import { EndpointHighNumberOfQueriesInsightTicket } from "./insightTickets/EndpointHighNumberOfQueriesInsightTicket";
import { EndpointQueryOptimizationV2InsightTicket } from "./insightTickets/EndpointQueryOptimizationV2InsightTicket";
import { EndpointScalingInsightTicket } from "./insightTickets/EndpointScalingInsightTicket";
import { EndpointScalingWithSpanInsightTicket } from "./insightTickets/EndpointScalingWithSpanInsightTicket";
import { EndpointSpanNPlusOneInsightTicket } from "./insightTickets/EndpointSpanNPlusOneInsightTicket";
import { SpanEndpointBottleneckInsightTicket } from "./insightTickets/SpanEndpointBottleneckInsightTicket";
import { SpanPerformanceAnomalyInsightTicket } from "./insightTickets/SpanPerformanceAnomalyInsightTicket";
Expand Down Expand Up @@ -121,7 +125,7 @@ export const InsightTicketRenderer = ({
if (isSpanScalingBadlyInsight(data.insight)) {
const ticketData = data as InsightTicketInfo<SpanScalingInsight>;
const selectedRootCause = data.insight.rootCauseSpans.find(
(r) => r.spanCodeObjectId == data.spanCodeObjectId
(r) => r.spanCodeObjectId === data.spanCodeObjectId
);
if (selectedRootCause) {
return (
Expand All @@ -143,6 +147,30 @@ export const InsightTicketRenderer = ({
}
}

if (isEndpointScalingInsight(data.insight)) {
const ticketData = data as InsightTicketInfo<EndpointScalingInsight>;

switch (data.insight.issueLocation) {
case "SpanRootCause":
case "Span":
return (
<EndpointScalingWithSpanInsightTicket
data={ticketData}
onClose={onClose}
backendInfo={backendInfo}
/>
);
case "Endpoint":
return (
<EndpointScalingInsightTicket
data={ticketData}
onClose={onClose}
backendInfo={backendInfo}
/>
);
}
}

if (isSpanPerformanceAnomalyInsight(data.insight)) {
const ticketData = data as InsightTicketInfo<SpanPerformanceAnomalyInsight>;
return (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import type { Meta, StoryObj } from "@storybook/react";
import { EndpointScalingInsightTicket } from ".";
import { mockedEndpointScalingInsight } from "../../../InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointScalingInsightCard/mockData";

// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction
const meta: Meta<typeof EndpointScalingInsightTicket> = {
title:
"Insights/InsightTicketRenderer/insightTickets/EndpointScalingInsightTicket",
component: EndpointScalingInsightTicket,
parameters: {
// More on how to position stories at: https://storybook.js.org/docs/react/configure/story-layout
layout: "fullscreen"
}
};

export default meta;

type Story = StoryObj<typeof meta>;

export const Default: Story = {
args: {
data: {
insight: mockedEndpointScalingInsight
}
}
};
Loading
Loading