diff --git a/src/components/Insights/common/InsightCard/InsightHeader/index.tsx b/src/components/Insights/common/InsightCard/InsightHeader/index.tsx
index fd45b7ab8..39dbf884b 100644
--- a/src/components/Insights/common/InsightCard/InsightHeader/index.tsx
+++ b/src/components/Insights/common/InsightCard/InsightHeader/index.tsx
@@ -6,7 +6,6 @@ import {
import { roundTo } from "../../../../../utils/roundTo";
import { ConfigContext } from "../../../../common/App/ConfigContext";
import { InfoCircleIcon } from "../../../../common/icons/InfoCircleIcon";
-import { WarningTriangleIcon } from "../../../../common/icons/WarningTriangleIcon";
import { Link } from "../../../../common/v3/Link";
import { NewTag } from "../../../../common/v3/NewTag";
import { Tag } from "../../../../common/v3/Tag";
@@ -17,8 +16,6 @@ import { InsightStatusBadge } from "./InsightStatusBadge";
import * as s from "./styles";
import { InsightHeaderProps } from "./types";
-const HIGH_CRITICALITY_THRESHOLD = 0.8;
-
const getTagType = (criticality: number): TagType => {
if (criticality < 0.2) {
return "lowSeverity";
@@ -68,7 +65,7 @@ export const InsightHeader = (props: InsightHeaderProps) => {
/>
)}
-
+
{insightTypeInfo?.label}
{insightTypeInfo?.description && (
}>
@@ -77,15 +74,8 @@ export const InsightHeader = (props: InsightHeaderProps) => {
)}
-
+
- {props.criticality > HIGH_CRITICALITY_THRESHOLD && (
-
-
-
-
-
- )}
{props.isAsync && }
{props.isNew && }
{props.status && }
diff --git a/src/components/Insights/common/InsightCard/InsightHeader/styles.ts b/src/components/Insights/common/InsightCard/InsightHeader/styles.ts
index c5e186a24..d29632416 100644
--- a/src/components/Insights/common/InsightCard/InsightHeader/styles.ts
+++ b/src/components/Insights/common/InsightCard/InsightHeader/styles.ts
@@ -1,5 +1,5 @@
import styled from "styled-components";
-import { bodyMediumTypography } from "../../../../common/App/typographies";
+import { bodySemiboldTypography } from "../../../../common/App/typographies";
export const Container = styled.div`
display: flex;
@@ -26,8 +26,8 @@ export const InfoContainer = styled.div`
display: flex;
`;
-export const Label = styled.div`
- ${bodyMediumTypography}
+export const Title = styled.div`
+ ${bodySemiboldTypography}
display: flex;
gap: 4px;
@@ -41,8 +41,3 @@ export const BadgeContainer = styled.div`
gap: 8px;
height: 24px;
`;
-
-export const WarningTriangleContainer = styled.div`
- display: flex;
- color: ${({ theme }) => theme.colors.v3.status.high};
-`;
diff --git a/src/components/Insights/common/InsightCard/ProductionAffectionBar/ProductionAffectionBar.stories.tsx b/src/components/Insights/common/InsightCard/ProductionAffectionBar/ProductionAffectionBar.stories.tsx
new file mode 100644
index 000000000..acc33650c
--- /dev/null
+++ b/src/components/Insights/common/InsightCard/ProductionAffectionBar/ProductionAffectionBar.stories.tsx
@@ -0,0 +1,26 @@
+import { Meta, StoryObj } from "@storybook/react";
+import { ProductionAffectionBar } from ".";
+
+// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction
+const meta: Meta = {
+ title: "Insights/common/InsightCard/ProductionAffectionBar",
+ component: ProductionAffectionBar,
+ 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;
+
+export const WithoutTicket: Story = {
+ args: {}
+};
+
+export const WithTicket: Story = {
+ args: {
+ isTicketCreated: true
+ }
+};
diff --git a/src/components/Insights/common/InsightCard/ProductionAffectionBar/index.tsx b/src/components/Insights/common/InsightCard/ProductionAffectionBar/index.tsx
new file mode 100644
index 000000000..07f89f3bf
--- /dev/null
+++ b/src/components/Insights/common/InsightCard/ProductionAffectionBar/index.tsx
@@ -0,0 +1,24 @@
+import { SparkleIcon } from "../../../../common/icons/16px/SparkleIcon";
+import { Link } from "../../../../common/v3/Link";
+import * as s from "./styles";
+import { ProductionAffectionBarProps } from "./types";
+
+export const ProductionAffectionBar = (props: ProductionAffectionBarProps) => {
+ const handleCreateTicketLinkClick = () => {
+ props.onCreateTicket();
+ };
+
+ return (
+
+
+
+
+ Could affect production
+ {props.isTicketCreated ? (
+ Ticket Created
+ ) : (
+ Create Ticket
+ )}
+
+ );
+};
diff --git a/src/components/Insights/common/InsightCard/ProductionAffectionBar/styles.ts b/src/components/Insights/common/InsightCard/ProductionAffectionBar/styles.ts
new file mode 100644
index 000000000..749f192fc
--- /dev/null
+++ b/src/components/Insights/common/InsightCard/ProductionAffectionBar/styles.ts
@@ -0,0 +1,34 @@
+import styled from "styled-components";
+import { footnoteRegularTypography } from "../../../../common/App/typographies";
+import { ContainerProps } from "./types";
+
+export const Container = styled.div`
+ ${footnoteRegularTypography}
+
+ border-radius: 4px;
+ border: 1px solid ${({ theme }) => theme.colors.v3.status.high};
+ background: ${({ theme, $isActive }) =>
+ $isActive
+ ? theme.colors.v3.status.backgroundHigh
+ : theme.colors.v3.pieChart.darkRed};
+ display: flex;
+ align-items: center;
+ padding: 6px 8px;
+ gap: 4px;
+`;
+
+export const SparkleIconContainer = styled.div`
+ color: ${({ theme }) => theme.colors.v3.status.high};
+`;
+
+export const Title = styled.span`
+ color: ${({ theme }) => theme.colors.v3.text.primary};
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ overflow: hidden;
+ margin-right: auto;
+`;
+
+export const TicketStatus = styled.div`
+ color: ${({ theme }) => theme.colors.v3.text.secondary};
+`;
diff --git a/src/components/Insights/common/InsightCard/ProductionAffectionBar/types.ts b/src/components/Insights/common/InsightCard/ProductionAffectionBar/types.ts
new file mode 100644
index 000000000..818f68783
--- /dev/null
+++ b/src/components/Insights/common/InsightCard/ProductionAffectionBar/types.ts
@@ -0,0 +1,8 @@
+export interface ProductionAffectionBarProps {
+ isTicketCreated: boolean;
+ onCreateTicket: () => void;
+}
+
+export interface ContainerProps {
+ $isActive: boolean;
+}
diff --git a/src/components/Insights/common/InsightCard/index.tsx b/src/components/Insights/common/InsightCard/index.tsx
index 69cb6b49e..f0bb65233 100644
--- a/src/components/Insights/common/InsightCard/index.tsx
+++ b/src/components/Insights/common/InsightCard/index.tsx
@@ -21,9 +21,11 @@ import { usePrevious } from "../../../../hooks/usePrevious";
import { sendTrackingEvent } from "../../../../utils/sendTrackingEvent";
import { Spinner } from "../../../Navigation/CodeButtonMenu/Spinner";
import { trackingEvents } from "../../tracking";
+import { ProductionAffectionBar } from "./ProductionAffectionBar";
import { useDismissalHandler } from "./useDismissalHandler";
const IS_NEW_TIME_LIMIT = 1000 * 60 * 10; // in milliseconds
+const HIGH_CRITICALITY_THRESHOLD = 0.8;
export const InsightCard = (props: InsightCardProps) => {
const [isRecalculatingStarted, setIsRecalculatingStarted] = useState(false);
@@ -32,6 +34,8 @@ export const InsightCard = (props: InsightCardProps) => {
const { isLoading, dismiss, show } = useDismissalHandler(props.insight.id);
const previousLoading = usePrevious(isLoading);
+ const isCritical = props.insight.criticality > HIGH_CRITICALITY_THRESHOLD;
+
useEffect(() => {
if (previousLoading && !isLoading) {
props.onRefresh(props.insight.type);
@@ -42,7 +46,7 @@ export const InsightCard = (props: InsightCardProps) => {
props.onRefresh(props.insight.type);
};
- const handleRecalculateClick = () => {
+ const handleRecheckButtonClick = () => {
props.insight.prefixedCodeObjectId &&
props.onRecalculate &&
props.onRecalculate(props.insight.id);
@@ -112,7 +116,7 @@ export const InsightCard = (props: InsightCardProps) => {
};
const handleDismissClick = () => {
- sendTrackingEvent(trackingEvents.DISMISS_BUTTON_CLICKED, {
+ sendTrackingEvent(trackingEvents.INSIGHT_CARD_DISMISS_BUTTON_CLICKED, {
insightType: props.insight.type
});
dismiss();
@@ -120,12 +124,31 @@ export const InsightCard = (props: InsightCardProps) => {
};
const handleShowClick = () => {
- sendTrackingEvent(trackingEvents.SHOW_BUTTON_CLICKED, {
+ sendTrackingEvent(trackingEvents.INSIGHT_CARD_SHOW_BUTTON_CLICKED, {
insightType: props.insight.type
});
show();
};
+ const openTicketInfo = (
+ spanCodeObjectId: string | undefined,
+ event: string
+ ) => {
+ if (props.onJiraButtonClick) {
+ props.onJiraButtonClick(spanCodeObjectId, event);
+ }
+ };
+
+ const handleCreateTicketLinkClick = () => {
+ sendTrackingEvent(trackingEvents.INSIGHT_CARD_CREATE_TICKET_LINK_CLICKED, {
+ insightType: props.insight.type
+ });
+ openTicketInfo(
+ props.jiraTicketInfo?.spanCodeObjectId,
+ "create ticket link clicked"
+ );
+ };
+
const renderActions = () => {
const buttonsToRender: {
tooltip: string;
@@ -152,7 +175,7 @@ export const InsightCard = (props: InsightCardProps) => {
)
@@ -167,7 +190,8 @@ export const InsightCard = (props: InsightCardProps) => {
isHintEnabled={props.jiraTicketInfo?.isHintEnabled}
spanCodeObjectId={props.jiraTicketInfo?.spanCodeObjectId}
label={"Ticket"}
- onTicketInfoButtonClick={props.onJiraButtonClick!}
+ onTicketInfoOpen={openTicketInfo}
+ insightType={props.insight.type}
{...btnProps}
/>
)
@@ -253,6 +277,12 @@ export const InsightCard = (props: InsightCardProps) => {
}
content={
+ {isCritical && (
+
+ )}
{props.insight.actualStartTime &&
renderRecalculationBlock(
props.insight.actualStartTime,
diff --git a/src/components/Insights/common/InsightCard/types.ts b/src/components/Insights/common/InsightCard/types.ts
index c23122bd5..30a25c574 100644
--- a/src/components/Insights/common/InsightCard/types.ts
+++ b/src/components/Insights/common/InsightCard/types.ts
@@ -24,7 +24,10 @@ export interface InsightCardProps {
isHintEnabled?: boolean;
spanCodeObjectId?: string;
};
- onJiraButtonClick?: (spanCodeObjectId: string, event: string) => void;
+ onJiraButtonClick?: (
+ spanCodeObjectId: string | undefined,
+ event: string
+ ) => void;
onGoToSpan: (spanCodeObjectId: string) => void;
}
diff --git a/src/components/Insights/common/insights/EndpointBottleneckInsight/index.tsx b/src/components/Insights/common/insights/EndpointBottleneckInsight/index.tsx
index 41ab2362f..a4be2f69d 100644
--- a/src/components/Insights/common/insights/EndpointBottleneckInsight/index.tsx
+++ b/src/components/Insights/common/insights/EndpointBottleneckInsight/index.tsx
@@ -1,6 +1,4 @@
import { getDurationString } from "../../../../../utils/getDurationString";
-import { sendTrackingEvent } from "../../../../../utils/sendTrackingEvent";
-import { trackingEvents } from "../../../tracking";
import { Info } from "../../Info";
import { InsightCard } from "../../InsightCard";
import { ColumnsContainer } from "../../InsightCard/ColumnsContainer";
@@ -20,12 +18,9 @@ export const EndpointBottleneckInsight = (
};
const handleTicketInfoButtonClick = (
- spanCodeObjectId: string,
+ spanCodeObjectId: string | undefined,
event: string
) => {
- sendTrackingEvent(trackingEvents.JIRA_TICKET_INFO_BUTTON_CLICKED, {
- insightType: insight.type
- });
props.onJiraTicketCreate &&
props.onJiraTicketCreate(insight, spanCodeObjectId, event);
};
diff --git a/src/components/Insights/common/insights/EndpointNPlusOneInsight/index.tsx b/src/components/Insights/common/insights/EndpointNPlusOneInsight/index.tsx
index e3d853862..73cbdf3f4 100644
--- a/src/components/Insights/common/insights/EndpointNPlusOneInsight/index.tsx
+++ b/src/components/Insights/common/insights/EndpointNPlusOneInsight/index.tsx
@@ -1,8 +1,6 @@
import { useContext } from "react";
import { getDurationString } from "../../../../../utils/getDurationString";
-import { sendTrackingEvent } from "../../../../../utils/sendTrackingEvent";
import { ConfigContext } from "../../../../common/App/ConfigContext";
-import { trackingEvents } from "../../../tracking";
import { InsightType, Trace } from "../../../types";
import { Info } from "../../Info";
import { InsightCard } from "../../InsightCard";
@@ -23,12 +21,9 @@ export const EndpointNPlusOneInsight = (
};
const handleTicketInfoButtonClick = (
- spanCodeObjectId: string,
+ spanCodeObjectId: string | undefined,
event: string
) => {
- sendTrackingEvent(trackingEvents.JIRA_TICKET_INFO_BUTTON_CLICKED, {
- insightType: props.insight.type
- });
props.onJiraTicketCreate &&
props.onJiraTicketCreate(props.insight, spanCodeObjectId, event);
};
diff --git a/src/components/Insights/common/insights/EndpointQueryOptimizationInsight/index.tsx b/src/components/Insights/common/insights/EndpointQueryOptimizationInsight/index.tsx
index 045e839b4..01e932707 100644
--- a/src/components/Insights/common/insights/EndpointQueryOptimizationInsight/index.tsx
+++ b/src/components/Insights/common/insights/EndpointQueryOptimizationInsight/index.tsx
@@ -1,10 +1,8 @@
import { ReactNode, useContext, useState } from "react";
import { getDurationString } from "../../../../../utils/getDurationString";
-import { sendTrackingEvent } from "../../../../../utils/sendTrackingEvent";
import { ConfigContext } from "../../../../common/App/ConfigContext";
import { Link } from "../../../../common/v3/Link";
import { Tooltip } from "../../../../common/v3/Tooltip";
-import { trackingEvents } from "../../../tracking";
import {
EndpointQueryOptimizationSpan,
InsightType,
@@ -55,12 +53,9 @@ export const EndpointQueryOptimizationInsight = (
};
const handleTicketInfoButtonClick = (
- spanCodeObjectId: string,
+ spanCodeObjectId: string | undefined,
event: string
) => {
- sendTrackingEvent(trackingEvents.JIRA_TICKET_INFO_BUTTON_CLICKED, {
- insightType: props.insight.type
- });
props.onJiraTicketCreate &&
props.onJiraTicketCreate(props.insight, spanCodeObjectId, event);
};
diff --git a/src/components/Insights/common/insights/HighNumberOfQueriesInsight/index.tsx b/src/components/Insights/common/insights/HighNumberOfQueriesInsight/index.tsx
index 72b42d51d..b56cb2009 100644
--- a/src/components/Insights/common/insights/HighNumberOfQueriesInsight/index.tsx
+++ b/src/components/Insights/common/insights/HighNumberOfQueriesInsight/index.tsx
@@ -1,8 +1,6 @@
-import { sendTrackingEvent } from "../../../../../utils/sendTrackingEvent";
import { InfoCircleIcon } from "../../../../common/icons/InfoCircleIcon";
import { Tag } from "../../../../common/v3/Tag";
import { Tooltip } from "../../../../common/v3/Tooltip";
-import { trackingEvents } from "../../../tracking";
import { InsightType, Trace } from "../../../types";
import { InsightCard } from "../../InsightCard";
import { ColumnsContainer } from "../../InsightCard/ColumnsContainer";
@@ -25,10 +23,10 @@ export const HighNumberOfQueriesInsight = (
props.onTraceButtonClick(trace, insightType, spanCodeObjectId);
};
- const handleCreateJiraTicketButtonClick = (event: string) => {
- sendTrackingEvent(trackingEvents.JIRA_TICKET_INFO_BUTTON_CLICKED, {
- insightType: insight.type
- });
+ const handleCreateJiraTicketButtonClick = (
+ spanCodeObjectId: string | undefined,
+ event: string
+ ) => {
props.onJiraTicketCreate &&
props.onJiraTicketCreate(insight, undefined, event);
};
diff --git a/src/components/Insights/common/insights/ScalingIssueInsight/index.tsx b/src/components/Insights/common/insights/ScalingIssueInsight/index.tsx
index f7c7290ec..87a489bfc 100644
--- a/src/components/Insights/common/insights/ScalingIssueInsight/index.tsx
+++ b/src/components/Insights/common/insights/ScalingIssueInsight/index.tsx
@@ -1,14 +1,12 @@
import { useContext } from "react";
import { usePagination } from "../../../../../hooks/usePagination";
import { getDurationString } from "../../../../../utils/getDurationString";
-import { sendTrackingEvent } from "../../../../../utils/sendTrackingEvent";
import { trimEndpointScheme } from "../../../../../utils/trimEndpointScheme";
import { ConfigContext } from "../../../../common/App/ConfigContext";
import { TraceIcon } from "../../../../common/icons/12px/TraceIcon";
import { Button } from "../../../../common/v3/Button";
import { JiraButton } from "../../../../common/v3/JiraButton";
import { Pagination } from "../../../../common/v3/Pagination";
-import { trackingEvents } from "../../../tracking";
import { InsightType, RootCauseSpanInfo, Trace } from "../../../types";
import { InsightCard } from "../../InsightCard";
import { ColumnsContainer } from "../../InsightCard/ColumnsContainer";
@@ -41,13 +39,9 @@ export const ScalingIssueInsight = (props: ScalingIssueInsightProps) => {
};
const handleCreateJiraTicketButtonClick = (
- spanCodeObjectId: string,
+ spanCodeObjectId: string | undefined,
event: string
) => {
- sendTrackingEvent(trackingEvents.JIRA_TICKET_INFO_BUTTON_CLICKED, {
- insightType: props.insight.type
- });
-
props.onJiraTicketCreate &&
props.onJiraTicketCreate(props.insight, spanCodeObjectId, event);
};
@@ -65,10 +59,11 @@ export const ScalingIssueInsight = (props: ScalingIssueInsightProps) => {
const buttons = [
];
@@ -124,7 +119,7 @@ export const ScalingIssueInsight = (props: ScalingIssueInsightProps) => {
{renderRootCause(props.insight.rootCauseSpans)}
{affectedEndpoints.length > 0 && (
- Affected endpoints:
+ Affected endpoints
{pageItems.map((endpoint) => {
const endpointRoute = trimEndpointScheme(endpoint.route);
return (
diff --git a/src/components/Insights/common/insights/SpanEndpointBottleneckInsight/index.tsx b/src/components/Insights/common/insights/SpanEndpointBottleneckInsight/index.tsx
index 253469ea1..c1a2c057f 100644
--- a/src/components/Insights/common/insights/SpanEndpointBottleneckInsight/index.tsx
+++ b/src/components/Insights/common/insights/SpanEndpointBottleneckInsight/index.tsx
@@ -1,14 +1,12 @@
import { ReactNode, useContext, useState } from "react";
import { isNull } from "../../../../../typeGuards/isNull";
import { getDurationString } from "../../../../../utils/getDurationString";
-import { sendTrackingEvent } from "../../../../../utils/sendTrackingEvent";
import { trimEndpointScheme } from "../../../../../utils/trimEndpointScheme";
import { ConfigContext } from "../../../../common/App/ConfigContext";
import { TraceIcon } from "../../../../common/icons/12px/TraceIcon";
import { Button } from "../../../../common/v3/Button";
import { Link } from "../../../../common/v3/Link";
import { Tooltip } from "../../../../common/v3/Tooltip";
-import { trackingEvents } from "../../../tracking";
import { BottleneckEndpointInfo, InsightType, Trace } from "../../../types";
import { Info } from "../../Info";
import { InsightCard } from "../../InsightCard";
@@ -56,10 +54,10 @@ export const SpanEndpointBottleneckInsight = (
props.onAssetLinkClick(spanCodeObjectId, props?.insight.type);
};
- const handleCreateJiraTicketButtonClick = (event: string) => {
- sendTrackingEvent(trackingEvents.JIRA_TICKET_INFO_BUTTON_CLICKED, {
- insightType: props.insight.type
- });
+ const handleCreateJiraTicketButtonClick = (
+ spanCodeObjectId: string | undefined,
+ event: string
+ ) => {
props.onJiraTicketCreate &&
props.onJiraTicketCreate(props.insight, undefined, event);
};
diff --git a/src/components/Insights/common/insights/SpanNPlusOneInsight/index.tsx b/src/components/Insights/common/insights/SpanNPlusOneInsight/index.tsx
index ffd937bbc..eae658f0f 100644
--- a/src/components/Insights/common/insights/SpanNPlusOneInsight/index.tsx
+++ b/src/components/Insights/common/insights/SpanNPlusOneInsight/index.tsx
@@ -1,13 +1,11 @@
import { ReactNode, useContext, useState } from "react";
import { getDurationString } from "../../../../../utils/getDurationString";
-import { sendTrackingEvent } from "../../../../../utils/sendTrackingEvent";
import { trimEndpointScheme } from "../../../../../utils/trimEndpointScheme";
import { ConfigContext } from "../../../../common/App/ConfigContext";
import { TraceIcon } from "../../../../common/icons/12px/TraceIcon";
import { Button } from "../../../../common/v3/Button";
import { Link } from "../../../../common/v3/Link";
import { Tooltip } from "../../../../common/v3/Tooltip";
-import { trackingEvents } from "../../../tracking";
import { InsightType, NPlusOneEndpointInfo, Trace } from "../../../types";
import { Info } from "../../Info";
import { InsightCard } from "../../InsightCard";
@@ -61,10 +59,10 @@ export const SpanNPlusOneInsight = (props: SpanNPlusOneInsightProps) => {
props.onTraceButtonClick(trace, insightType, spanCodeObjectId);
};
- const handleCreateJiraTicketButtonClick = (event: string) => {
- sendTrackingEvent(trackingEvents.JIRA_TICKET_INFO_BUTTON_CLICKED, {
- insightType: props.insight.type
- });
+ const handleCreateJiraTicketButtonClick = (
+ spanCodeObjectId: string | undefined,
+ event: string
+ ) => {
props.onJiraTicketCreate &&
props.onJiraTicketCreate(props.insight, undefined, event);
};
diff --git a/src/components/Insights/common/insights/SpanQueryOptimizationInsight/index.tsx b/src/components/Insights/common/insights/SpanQueryOptimizationInsight/index.tsx
index 9ee5dc08d..6297b03c5 100644
--- a/src/components/Insights/common/insights/SpanQueryOptimizationInsight/index.tsx
+++ b/src/components/Insights/common/insights/SpanQueryOptimizationInsight/index.tsx
@@ -1,11 +1,9 @@
import { useContext } from "react";
import { usePagination } from "../../../../../hooks/usePagination";
import { getDurationString } from "../../../../../utils/getDurationString";
-import { sendTrackingEvent } from "../../../../../utils/sendTrackingEvent";
import { trimEndpointScheme } from "../../../../../utils/trimEndpointScheme";
import { ConfigContext } from "../../../../common/App/ConfigContext";
import { Pagination } from "../../../../common/v3/Pagination";
-import { trackingEvents } from "../../../tracking";
import { InsightType, Trace } from "../../../types";
import { InsightCard } from "../../InsightCard";
import { ColumnsContainer } from "../../InsightCard/ColumnsContainer";
@@ -41,11 +39,10 @@ export const SpanQueryOptimizationInsight = (
props.onTraceButtonClick(trace, insightType, spanCodeObjectId);
};
- const handleCreateJiraTicketButtonClick = (event: string) => {
- sendTrackingEvent(trackingEvents.JIRA_TICKET_INFO_BUTTON_CLICKED, {
- insightType: props.insight.type
- });
-
+ const handleCreateJiraTicketButtonClick = (
+ spanCodeObjectId: string | undefined,
+ event: string
+ ) => {
props.onJiraTicketCreate &&
props.onJiraTicketCreate(
props.insight,
@@ -68,7 +65,7 @@ export const SpanQueryOptimizationInsight = (
Query is slow compared to other{" "}
- {props.insight.dbStatement.toUpperCase()} requests.
+ {props.insight.dbStatement.toUpperCase()} requests
{endpoints.length > 0 && (
<>
- Affected endpoints:
+ Affected endpoints
{pageItems.map((x) => {
const spanCodeObjectId = x.endpointInfo.spanCodeObjectId;
diff --git a/src/components/Insights/common/insights/TrafficInsight/index.tsx b/src/components/Insights/common/insights/TrafficInsight/index.tsx
index d0341201b..45118d063 100644
--- a/src/components/Insights/common/insights/TrafficInsight/index.tsx
+++ b/src/components/Insights/common/insights/TrafficInsight/index.tsx
@@ -54,7 +54,7 @@ export const TrafficInsight = (props: TrafficInsightProps) => {
{getDescription(props.insight.type)}
-
+
diff --git a/src/components/Insights/index.tsx b/src/components/Insights/index.tsx
index 87c2bc054..446bbf409 100644
--- a/src/components/Insights/index.tsx
+++ b/src/components/Insights/index.tsx
@@ -120,7 +120,10 @@ const renderInsightTicket = (
);
}
- if (isEndpointHighNumberOfQueriesInsight(data.insight)) {
+ if (
+ isEndpointHighNumberOfQueriesInsight(data.insight) &&
+ data.spanCodeObjectId
+ ) {
const ticketData =
data as InsightTicketInfo;
return (
diff --git a/src/components/Insights/tracking.ts b/src/components/Insights/tracking.ts
index 6a8b0f35b..a5565ecad 100644
--- a/src/components/Insights/tracking.ts
+++ b/src/components/Insights/tracking.ts
@@ -6,13 +6,11 @@ export const trackingEvents = addPrefix(
TRACKING_PREFIX,
{
JIRA_TICKET_INFO_BUTTON_CLICKED: "jira ticket info button clicked",
- JIRA_TICKET_FIELD_COPY_BUTTON_CLICKED:
- "jira ticket field copy button clicked",
- JIRA_TICKET_ATTACHMENT_DOWNLOAD_BUTTON_CLICKED:
- "jira ticket attachment download button clicked",
JIRA_TICKET_HINT_CLOSED: "jira ticket hint closed",
- DISMISS_BUTTON_CLICKED: "insight dismiss button clicked",
- SHOW_BUTTON_CLICKED: "insight show button clicked",
+ INSIGHT_CARD_DISMISS_BUTTON_CLICKED: "insight card dismiss button clicked",
+ INSIGHT_CARD_SHOW_BUTTON_CLICKED: "insight card show button clicked",
+ INSIGHT_CARD_CREATE_TICKET_LINK_CLICKED:
+ "insight card create ticket link clicked",
REFRESH_BUTTON_CLICKED: "refresh button clicked"
},
" "
diff --git a/src/components/common/App/themes/darkTheme.ts b/src/components/common/App/themes/darkTheme.ts
index 3ed52c6ee..ac92a3bdf 100644
--- a/src/components/common/App/themes/darkTheme.ts
+++ b/src/components/common/App/themes/darkTheme.ts
@@ -288,7 +288,8 @@ export const darkTheme: ThemeColors = {
azureFill: v3colors.azure[200],
azureStroke: v3colors.azure[300],
brightOrangeFill: v3colors.brightOrange[200],
- brightOrangeStroke: v3colors.brightOrange[300]
+ brightOrangeStroke: v3colors.brightOrange[300],
+ darkRed: v3colors.red[500]
}
}
};
diff --git a/src/components/common/App/themes/lightTheme.ts b/src/components/common/App/themes/lightTheme.ts
index ba3b4ccfc..ceed7b28e 100644
--- a/src/components/common/App/themes/lightTheme.ts
+++ b/src/components/common/App/themes/lightTheme.ts
@@ -286,7 +286,8 @@ export const lightTheme: ThemeColors = {
azureFill: v3colors.azure[200],
azureStroke: v3colors.azure[100],
brightOrangeFill: v3colors.brightOrange[200],
- brightOrangeStroke: v3colors.brightOrange[100]
+ brightOrangeStroke: v3colors.brightOrange[100],
+ darkRed: v3colors.red[600]
}
}
};
diff --git a/src/components/common/App/typographies.ts b/src/components/common/App/typographies.ts
index 1c6374f38..e6f1850e8 100644
--- a/src/components/common/App/typographies.ts
+++ b/src/components/common/App/typographies.ts
@@ -95,7 +95,7 @@ export const bodyRegularTypography = css`
line-height: ${typographies.body.lineHeight}px;
`;
-export const bodyMediumTypography = css`
+export const bodySemiboldTypography = css`
font-size: ${typographies.body.fontSize}px;
font-weight: ${typographies.body.fontWeight.medium};
line-height: ${typographies.body.lineHeight}px;
diff --git a/src/components/common/App/v3colors.ts b/src/components/common/App/v3colors.ts
index 8f88cf3c5..0a8bddaf5 100644
--- a/src/components/common/App/v3colors.ts
+++ b/src/components/common/App/v3colors.ts
@@ -46,7 +46,9 @@ export const v3colors = {
100: "#ffdfdf",
200: "#ff7e7e",
300: "#da2d5f",
- 400: "#3d2327"
+ 400: "#3d2327",
+ 500: "#241e21",
+ 600: "#ffeeee"
},
orange: {
100: "#ffe0ce",
diff --git a/src/components/common/icons/16px/SparkleIcon.tsx b/src/components/common/icons/16px/SparkleIcon.tsx
new file mode 100644
index 000000000..d187948b4
--- /dev/null
+++ b/src/components/common/icons/16px/SparkleIcon.tsx
@@ -0,0 +1,33 @@
+import React from "react";
+import { useIconProps } from "../hooks";
+import { IconProps } from "../types";
+
+const SparkleIconComponent = (props: IconProps) => {
+ const { size, color } = useIconProps(props);
+
+ return (
+
+ );
+};
+
+export const SparkleIcon = React.memo(SparkleIconComponent);
diff --git a/src/components/common/v3/JiraButton/index.tsx b/src/components/common/v3/JiraButton/index.tsx
index 33ddf2eef..b6d36ee7b 100644
--- a/src/components/common/v3/JiraButton/index.tsx
+++ b/src/components/common/v3/JiraButton/index.tsx
@@ -1,6 +1,8 @@
import { ForwardedRef, forwardRef, useState } from "react";
import { useTheme } from "styled-components";
import { openURLInDefaultBrowser } from "../../../../utils/openURLInDefaultBrowser";
+import { sendTrackingEvent } from "../../../../utils/sendTrackingEvent";
+import { trackingEvents } from "../../../Insights/tracking";
import { MenuList } from "../../../Navigation/common/MenuList";
import { Popup } from "../../../Navigation/common/Popup";
import { PencilIcon } from "../../../common/icons/12px/PencilIcon";
@@ -16,28 +18,47 @@ export const JiraButtonComponent = (
{
ticketLink,
isHintEnabled,
- onTicketInfoButtonClick,
+ onTicketInfoOpen,
spanCodeObjectId,
buttonType,
- label
+ label,
+ insightType
}: JiraButtonProps,
ref: ForwardedRef
) => {
- const [isJiraPopoverOpen, setIsJiraPopoverOpen] = useState(false);
+ const [isMenuOpen, setIsMenuOpen] = useState(false);
const theme = useTheme();
- const handleJiraButtonClick = () => {
- setIsJiraPopoverOpen(!isJiraPopoverOpen);
+ const handleMenuOpenChange = (isOpen: boolean) => {
+ sendTrackingEvent(trackingEvents.JIRA_TICKET_INFO_BUTTON_CLICKED, {
+ insightType
+ });
+ setIsMenuOpen(isOpen);
};
- const handleViewButtonClick = () => {
- handleJiraButtonClick();
+ const openTicketInfo = (event: string) => {
+ onTicketInfoOpen(spanCodeObjectId, event);
+ };
+
+ const handleViewMenuItemClick = () => {
+ setIsMenuOpen(false);
ticketLink && openURLInDefaultBrowser(ticketLink);
};
- const openTicketInfo = (event: string) => {
- handleJiraButtonClick();
- onTicketInfoButtonClick(spanCodeObjectId, event);
+ const handleEditMenuItemClick = () => {
+ setIsMenuOpen(false);
+ openTicketInfo("edit menu item click");
+ };
+
+ const handleJiraButtonClick = () => {
+ sendTrackingEvent(trackingEvents.JIRA_TICKET_INFO_BUTTON_CLICKED, {
+ insightType
+ });
+ openTicketInfo("jira button click");
+ };
+
+ const handleTryButtonClick = () => {
+ openTicketInfo("try now button click");
};
const renderButton = () => (
@@ -52,20 +73,20 @@ export const JiraButtonComponent = (
icon: ,
label: "View",
id: "view",
- onClick: handleViewButtonClick
+ onClick: handleViewMenuItemClick
},
{
icon: ,
label: "Edit",
id: "edit",
- onClick: () => openTicketInfo("edit menu item click")
+ onClick: handleEditMenuItemClick
}
]}
/>
}
- isOpen={isJiraPopoverOpen}
- onOpenChange={handleJiraButtonClick}
+ isOpen={isMenuOpen}
+ onOpenChange={handleMenuOpenChange}
placement={"bottom-start"}
>