openTicketInfo("jira button click")}
+ />
)}
);
return (
-
-
-
-
-
- Get Ticket Info
-
-
- You can now easily create a ticket using information from Digma
-
- openTicketInfo("try now button click")}
- >
- Try now
-
-
- }
- isOpen={isHintEnabled}
- >
- {renderButton()}
-
+
+
+
+
+
+
+ Get Ticket Info
+
+
+ You can now easily create a ticket using information from Digma
+
+ openTicketInfo("try now button click")}
+ label={"Try now"}
+ />
+
+ }
+ isOpen={Boolean(isHintEnabled)}
+ >
+ {renderButton()}
+
+
);
};
+
+export const JiraButton = forwardRef(JiraButtonComponent);
diff --git a/src/components/common/v3/JiraButton/styles.ts b/src/components/common/v3/JiraButton/styles.ts
index 105905961..235525a1f 100644
--- a/src/components/common/v3/JiraButton/styles.ts
+++ b/src/components/common/v3/JiraButton/styles.ts
@@ -1,5 +1,6 @@
import styled from "styled-components";
-import { Button } from "../../Button";
+import { subscriptSemiboldTypography } from "../../App/typographies";
+import { Button } from "../../v3/Button";
export const HintContainer = styled.div`
display: flex;
@@ -7,21 +8,22 @@ export const HintContainer = styled.div`
gap: 4px;
padding: 4px;
width: 235px;
- color: ${({ theme }) => theme.colors.text.subtext};
+ color: ${({ theme }) => theme.colors.v3.text.secondary};
word-break: keep-all;
`;
export const HintHeader = styled.div`
+ ${subscriptSemiboldTypography}
+
display: flex;
gap: 4px;
align-items: center;
- font-weight: 500;
- color: ${({ theme }) => theme.colors.text.base};
+ color: ${({ theme }) => theme.colors.v3.text.primary};
`;
export const HintIconContainer = styled.div`
display: flex;
- color: ${({ theme }) => theme.colors.icon.primary};
+ color: ${({ theme }) => theme.colors.v3.icon.primary};
`;
export const TryNowButton = styled(Button)`
diff --git a/src/components/common/v3/JiraButton/types.ts b/src/components/common/v3/JiraButton/types.ts
index 0569ff726..6571d7159 100644
--- a/src/components/common/v3/JiraButton/types.ts
+++ b/src/components/common/v3/JiraButton/types.ts
@@ -1,5 +1,11 @@
-export interface JiraButtonProps {
- onTicketInfoButtonClick(event: string): void;
+import { BaseButtonProps } from "../Button/types";
+
+export interface JiraButtonProps extends BaseButtonProps {
+ onTicketInfoButtonClick(
+ spanCodeObjectId: string | undefined,
+ event: string
+ ): void;
ticketLink?: string | null;
isHintEnabled?: boolean;
+ spanCodeObjectId?: string;
}
diff --git a/src/components/common/v3/Link/index.tsx b/src/components/common/v3/Link/index.tsx
new file mode 100644
index 000000000..d0c7df5f8
--- /dev/null
+++ b/src/components/common/v3/Link/index.tsx
@@ -0,0 +1,32 @@
+import { ForwardedRef, MouseEvent, forwardRef } from "react";
+import * as s from "./styles";
+import { LinkProps } from "./types";
+
+const LinkComponent = (
+ props: LinkProps,
+ ref: ForwardedRef
+) => {
+ const handleClick = (e: MouseEvent) => {
+ if (props.onClick) {
+ if (!props.href) {
+ e.preventDefault();
+ }
+ props.onClick(e);
+ }
+ };
+
+ return (
+
+ {props.children}
+
+ );
+};
+
+export const Link = forwardRef(LinkComponent);
diff --git a/src/components/common/v3/Link/styles.ts b/src/components/common/v3/Link/styles.ts
new file mode 100644
index 000000000..01644c180
--- /dev/null
+++ b/src/components/common/v3/Link/styles.ts
@@ -0,0 +1,51 @@
+import styled from "styled-components";
+import { footnoteRegularTypography } from "../../App/typographies";
+
+export const Link = styled.a`
+ ${footnoteRegularTypography}
+
+ cursor: pointer;
+ text-decoration: none;
+ color: ${({ theme }) => theme.colors.v3.text.link};
+ display: block;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ overflow: hidden;
+
+ &:hover,
+ &:focus {
+ color: ${({ theme }) => {
+ switch (theme.mode) {
+ case "light":
+ return "#002d61";
+ case "dark":
+ case "dark-jetbrains":
+ return "#e2e7ff";
+ }
+ }};
+ }
+
+ &:active {
+ color: ${({ theme }) => {
+ switch (theme.mode) {
+ case "light":
+ return "#002d61";
+ case "dark":
+ case "dark-jetbrains":
+ return "#7891d0";
+ }
+ }};
+ }
+
+ &:disabled {
+ color: ${({ theme }) => {
+ switch (theme.mode) {
+ case "light":
+ return "#b9c0d4";
+ case "dark":
+ case "dark-jetbrains":
+ return "#49494d";
+ }
+ }};
+ }
+`;
diff --git a/src/components/common/v3/Link/types.ts b/src/components/common/v3/Link/types.ts
new file mode 100644
index 000000000..774980b22
--- /dev/null
+++ b/src/components/common/v3/Link/types.ts
@@ -0,0 +1,11 @@
+import { MouseEvent, ReactNode } from "react";
+
+export interface LinkProps {
+ href?: string;
+ target?: string;
+ rel?: string;
+ onClick?: (e: MouseEvent) => void;
+ disabled?: boolean;
+ children: ReactNode;
+ className?: string;
+}
diff --git a/src/components/common/v3/Toggle/index.tsx b/src/components/common/v3/Toggle/index.tsx
new file mode 100644
index 000000000..fa321afbe
--- /dev/null
+++ b/src/components/common/v3/Toggle/index.tsx
@@ -0,0 +1,22 @@
+import * as s from "./styles";
+import { ToggleProps, ToggleValue } from "./types";
+
+export const Toggle = (props: ToggleProps) => {
+ const handleOptionButtonClick = (value: T) => {
+ props.onValueChange(value);
+ };
+
+ return (
+
+ {props.options.map((option) => (
+ handleOptionButtonClick(option.value)}
+ >
+ {option.label}
+
+ ))}
+
+ );
+};
diff --git a/src/components/common/v3/Toggle/styles.ts b/src/components/common/v3/Toggle/styles.ts
new file mode 100644
index 000000000..ddd4ccb5e
--- /dev/null
+++ b/src/components/common/v3/Toggle/styles.ts
@@ -0,0 +1,29 @@
+import styled from "styled-components";
+import { footnoteRegularTypography } from "../../App/typographies";
+import { OptionButtonProps } from "./types";
+
+export const Container = styled.div`
+ display: flex;
+ border-radius: 4px;
+ padding: 3px;
+ gap: 4px;
+ width: fit-content;
+ border: 1px solid ${({ theme }) => theme.colors.v3.stroke.tertiary};
+ background: ${({ theme }) => theme.colors.v3.surface.secondary};
+`;
+
+export const OptionButton = styled.button`
+ ${footnoteRegularTypography}
+
+ font-family: inherit;
+ border: none;
+ outline: none;
+ border-radius: 4px;
+ padding: 2px 4px;
+ cursor: pointer;
+ user-select: none;
+ color: ${({ theme, $selected }) =>
+ $selected ? theme.colors.v3.text.white : theme.colors.v3.text.primary};
+ background: ${({ theme, $selected }) =>
+ $selected ? theme.colors.v3.surface.brandTertiary : "transparent"};
+`;
diff --git a/src/components/common/v3/Toggle/types.ts b/src/components/common/v3/Toggle/types.ts
new file mode 100644
index 000000000..bd726acb1
--- /dev/null
+++ b/src/components/common/v3/Toggle/types.ts
@@ -0,0 +1,16 @@
+export type ToggleValue = string | number;
+
+export interface ToggleOption {
+ value: T;
+ label: string;
+}
+
+export interface ToggleProps {
+ options: ToggleOption[];
+ onValueChange: (value: T) => void;
+ value: T;
+}
+
+export interface OptionButtonProps {
+ $selected: boolean;
+}
diff --git a/src/components/common/v3/Tooltip/index.tsx b/src/components/common/v3/Tooltip/index.tsx
index 7baeec374..de613a2c5 100644
--- a/src/components/common/v3/Tooltip/index.tsx
+++ b/src/components/common/v3/Tooltip/index.tsx
@@ -145,7 +145,7 @@ export const Tooltip = (props: TooltipProps) => {
>
{renderArrow(true)}
{renderArrow(false)}
- {props.title}
+ {props.title}
)}
diff --git a/src/components/common/v3/Tooltip/styles.ts b/src/components/common/v3/Tooltip/styles.ts
index 9cd6370bf..36d8a55ca 100644
--- a/src/components/common/v3/Tooltip/styles.ts
+++ b/src/components/common/v3/Tooltip/styles.ts
@@ -1,12 +1,13 @@
import styled from "styled-components";
import { LAYERS } from "../../App/styles";
import { footnoteRegularTypography } from "../../App/typographies";
+import { TooltipComponentProps } from "./types";
export const TooltipContainer = styled.div`
z-index: ${LAYERS.TOOLTIP};
`;
-export const Tooltip = styled.div`
+export const Tooltip = styled.div`
${footnoteRegularTypography}
padding: 4px;
@@ -16,5 +17,5 @@ export const Tooltip = styled.div`
color: ${({ theme }) => theme.colors.v3.text.primary};
background: ${({ theme }) => theme.colors.v3.surface.primary};
border: 1px solid ${({ theme }) => theme.colors.v3.stroke.tertiary};
- max-width: 200px;
+ ${({ $fullWidth }) => ($fullWidth ? "" : "max-width: 200px;")}
`;
diff --git a/src/components/common/v3/Tooltip/types.ts b/src/components/common/v3/Tooltip/types.ts
index f20bb78b9..712fbf0f7 100644
--- a/src/components/common/v3/Tooltip/types.ts
+++ b/src/components/common/v3/Tooltip/types.ts
@@ -12,4 +12,9 @@ export interface TooltipProps {
placement?: Placement;
style?: React.CSSProperties;
isOpen?: boolean;
+ fullWidth?: boolean;
+}
+
+export interface TooltipComponentProps {
+ $fullWidth?: boolean;
}
diff --git a/src/containers/Insights/styles.ts b/src/containers/Insights/styles.ts
index c8455f5aa..5a50935a9 100644
--- a/src/containers/Insights/styles.ts
+++ b/src/containers/Insights/styles.ts
@@ -1,15 +1,7 @@
import { createGlobalStyle } from "styled-components";
export const GlobalStyle = createGlobalStyle`
- body {
- background: ${({ theme }) => {
- switch (theme.mode) {
- case "light":
- return "#fbfdff";
- case "dark":
- case "dark-jetbrains":
- return "#3d3f41";
- }
- }};
- }
+ /* body {
+ // TODO: Add global styles
+ } */
`;
diff --git a/src/styled.d.ts b/src/styled.d.ts
index dbca0ba82..786de5a05 100644
--- a/src/styled.d.ts
+++ b/src/styled.d.ts
@@ -70,7 +70,9 @@ export interface ThemeColors {
secondary: string;
brandPrimary: string;
brandSecondary: string;
+ brandTertiary: string;
brandDark: string;
+ brandDarkest: string;
sidePanelHeader: string;
};
text: {
@@ -91,7 +93,6 @@ export interface ThemeColors {
brandSecondary: string;
};
icon: {
- white: string;
primary: string;
secondary: string;
tertiary: string;
@@ -99,6 +100,7 @@ export interface ThemeColors {
brandPrimary: string;
brandSecondary: string;
brandTertiary: string;
+ white: string;
};
status: {
backgroundHigh: string;
@@ -110,11 +112,6 @@ export interface ThemeColors {
backgroundSuccess: string;
success: string;
};
- barChart: {
- pink: string;
- purple: string;
- blue: string;
- };
pieChart: {
pinkFill: string;
pinkStroke: string;
@@ -125,6 +122,11 @@ export interface ThemeColors {
brightOrangeFill: string;
brightOrangeStroke: string;
};
+ barChart: {
+ pink: string;
+ purple: string;
+ blue: string;
+ };
};
}
diff --git a/src/types.ts b/src/types.ts
index 3fb02276e..ac852f2fd 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -16,9 +16,9 @@ export enum InsightType {
LowUsage = "LowUsage",
NormalUsage = "NormalUsage",
HighUsage = "HighUsage",
- SlowestSpans = "SlowestSpans",
+ SlowestSpans = "SlowestSpans", // deprecated
EndpointBottleneck = "EndpointBottleneck",
- EndpointSpanNPlusOne = "EndpointSpaNPlusOne",
+ EndpointSpanNPlusOne = "EndpointSpaNPlusOne", // deprecated
EndpointSpanNPlusOneV2 = "EndpointSpanNPlusOne",
SpanUsages = "SpanUsages",
SpanNPlusOne = "SpaNPlusOne",
@@ -26,10 +26,10 @@ export enum InsightType {
SpanDurations = "SpanDurations",
SpanScalingBadly = "SpanScaling",
SpanDurationBreakdown = "SpanDurationBreakdown",
- EndpointDurationSlowdown = "EndpointDurationSlowdown",
+ EndpointDurationSlowdown = "EndpointDurationSlowdown", // deprecated
EndpointBreakdown = "EndpointBreakdown",
- SpanScalingWell = "SpanScalingWell",
- SpanScalingInsufficientData = "SpanScalingInsufficientData",
+ SpanScalingWell = "SpanScalingWell", // deprecated
+ SpanScalingInsufficientData = "SpanScalingInsufficientData", // deprecated
EndpointSessionInView = "EndpointSessionInView",
EndpointChattyApi = "EndpointChattyApi",
EndpointHighNumberOfQueries = "EndpointHighNumberOfQueries",
diff --git a/src/utils/getInsightCriticalityColor.tsx b/src/utils/getInsightCriticalityColor.tsx
new file mode 100644
index 000000000..069c3502f
--- /dev/null
+++ b/src/utils/getInsightCriticalityColor.tsx
@@ -0,0 +1,16 @@
+import { DefaultTheme } from "styled-components";
+
+export const getInsightCriticalityColor = (
+ criticality: number,
+ theme: DefaultTheme
+): string => {
+ if (criticality < 0.2) {
+ return theme.colors.v3.status.low;
+ }
+
+ if (criticality < 0.6) {
+ return theme.colors.v3.status.medium;
+ }
+
+ return theme.colors.v3.status.high;
+};
diff --git a/src/utils/getInsightTypeInfo.ts b/src/utils/getInsightTypeInfo.ts
index 6e9c4baf7..50ddcf091 100644
--- a/src/utils/getInsightTypeInfo.ts
+++ b/src/utils/getInsightTypeInfo.ts
@@ -16,15 +16,15 @@ import { WarningCircleIcon } from "../components/common/icons/WarningCircleIcon"
import { IconProps } from "../components/common/icons/types";
import { InsightType } from "../types";
+export interface InsightTypeInfo {
+ icon: MemoExoticComponent<(props: IconProps) => JSX.Element>;
+ label: string;
+ description?: () => JSX.Element;
+}
+
export const getInsightTypeInfo = (
type: string
-):
- | {
- icon: MemoExoticComponent<(props: IconProps) => JSX.Element>;
- label: string;
- description?: () => JSX.Element;
- }
- | undefined => {
+): InsightTypeInfo | undefined => {
const insightTypeInfoMap: Record<
string,
{
@@ -58,16 +58,28 @@ export const getInsightTypeInfo = (
icon: MeterHighIcon,
label: "Endpoint High Traffic"
},
+ // deprecated
[InsightType.SlowestSpans]: {
icon: BottleneckIcon,
label: "Bottleneck",
description: descriptionProvider.BottleneckDescription
},
+ [InsightType.EndpointBottleneck]: {
+ icon: BottleneckIcon,
+ label: "Bottleneck",
+ description: descriptionProvider.BottleneckDescription
+ },
+ // deprecated
[InsightType.EndpointSpanNPlusOne]: {
icon: SQLDatabaseIcon,
label: "Suspected N-Plus-1",
description: descriptionProvider.NPlusOneDescription
},
+ [InsightType.EndpointSpanNPlusOneV2]: {
+ icon: SQLDatabaseIcon,
+ label: "Suspected N-Plus-1",
+ description: descriptionProvider.NPlusOneDescription
+ },
[InsightType.SpanNPlusOne]: {
icon: SQLDatabaseIcon,
label: "Suspected N-Plus-1",
@@ -95,18 +107,25 @@ export const getInsightTypeInfo = (
icon: ClockWithTicksIcon,
label: "Duration Breakdown"
},
+ // deprecated
[InsightType.EndpointDurationSlowdown]: {
icon: SnailIcon,
label: "Duration Slowdown Source Detected"
},
+ [InsightType.EndpointSlowdownSource]: {
+ icon: SnailIcon,
+ label: "Duration Slowdown Source Detected"
+ },
[InsightType.EndpointBreakdown]: {
icon: PieChartIcon,
label: "Request Breakdown"
},
+ // deprecated
[InsightType.SpanScalingWell]: {
icon: ScalesIcon,
label: "No Scaling Issue Detected"
},
+ // deprecated
[InsightType.SpanScalingInsufficientData]: {
icon: ScalesIcon,
label: "Performance at Scale"
diff --git a/src/utils/getInsightTypeOrderPriority.ts b/src/utils/getInsightTypeOrderPriority.ts
index 68fd09209..4e2e7cde7 100644
--- a/src/utils/getInsightTypeOrderPriority.ts
+++ b/src/utils/getInsightTypeOrderPriority.ts
@@ -10,11 +10,11 @@ export const getInsightTypeOrderPriority = (type: string): number => {
[InsightType.EndpointBreakdown]: 5,
[InsightType.HighUsage]: 10,
[InsightType.SlowEndpoint]: 20,
- [InsightType.EndpointDurationSlowdown]: 25,
+ [InsightType.EndpointSlowdownSource]: 25,
[InsightType.LowUsage]: 30,
- [InsightType.SlowestSpans]: 40,
+ [InsightType.EndpointBottleneck]: 40,
[InsightType.NormalUsage]: 50,
- [InsightType.EndpointSpanNPlusOne]: 55,
+ [InsightType.EndpointSpanNPlusOneV2]: 55,
[InsightType.EndpointSessionInView]: 56,
[InsightType.EndpointChattyApi]: 57,
[InsightType.EndpointHighNumberOfQueries]: 58,
@@ -23,9 +23,7 @@ export const getInsightTypeOrderPriority = (type: string): number => {
// Span insights
[InsightType.SpanDurations]: 60,
[InsightType.SpanUsages]: 61,
- [InsightType.SpanScalingInsufficientData]: 62,
[InsightType.SpanScalingBadly]: 63,
- [InsightType.SpanScalingWell]: 64,
[InsightType.SpanNPlusOne]: 65,
[InsightType.SpanEndpointBottleneck]: 67,
[InsightType.SpanDurationBreakdown]: 68,