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
1 change: 1 addition & 0 deletions src/components/Insights/BottleneckInsight/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const BottleneckInsight = (props: BottleneckInsightProps) => {

return (
<InsightCard
title={props.insight.spanInfo?.displayName}
data={props.insight}
content={
<>
Expand Down
1 change: 1 addition & 0 deletions src/components/Insights/DurationBreakdownInsight/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export const DurationBreakdownInsight = (
return (
<InsightCard
data={props.insight}
title={props.insight.spanInfo?.displayName}
content={
<s.EntryList>
{pageItems.map((entry) => {
Expand Down
1 change: 1 addition & 0 deletions src/components/Insights/DurationInsight/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ export const DurationInsight = (props: DurationInsightProps) => {
return (
<InsightCard
data={props.insight}
title={props.insight.spanInfo?.displayName}
isRecent={isLastCallRecent}
content={
<s.Container>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export const DurationSlowdownSourceInsight = (
return (
<InsightCard
data={props.insight}
title={props.insight.spanInfo?.displayName}
content={
<s.Container>
<Description>Found spans slowing the endpoint</Description>
Expand Down
1 change: 1 addition & 0 deletions src/components/Insights/EndpointNPlusOneInsight/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export const EndpointNPlusOneInsight = (
return (
<InsightCard
data={props.insight}
title={props.insight.spanInfo?.displayName}
content={
<s.ContentContainer>
<Description>Check the following locations:</Description>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export const EndpointQueryOptimizationInsight = (
return (
<InsightCard
data={props.insight}
title={props.insight.spanInfo?.displayName}
content={
<s.ContentContainer>
<Description>Check the following locations:</Description>
Expand Down
1 change: 1 addition & 0 deletions src/components/Insights/ExcessiveAPICallsInsight/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export const ExcessiveAPICallsInsight = (
return (
<InsightCard
data={props.insight}
title={props.insight.spanInfo?.displayName}
content={
<s.ContentContainer>
<Description>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export const HighNumberOfQueriesInsight = (
return (
<InsightCard
data={insight}
title={props.insight.spanInfo?.displayName}
content={
<s.ContentContainer>
<Description>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type Story = StoryObj<typeof meta>;

export const Default: Story = {
args: {
title: "asdasdasd",
data: {
firstDetected: "2023-12-05T17:25:47.010Z",
lastDetected: "2024-01-05T13:14:47.010Z",
Expand Down
196 changes: 105 additions & 91 deletions src/components/Insights/InsightCard/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { useState } from "react";
import { useContext, useState } from "react";
import { useTheme } from "styled-components";
import { PERCENTILES } from "../../../constants";
import { isString } from "../../../typeGuards/isString";
import { formatTimeDistance } from "../../../utils/formatTimeDistance";
import { getInsightImportanceColor } from "../../../utils/getInsightImportanceColor";
import { getInsightTypeInfo } from "../../../utils/getInsightTypeInfo";
import { ConfigContext } from "../../common/App/ConfigContext";
import { Badge } from "../../common/Badge";
import { Card } from "../../common/Card";
import { KebabMenuButton } from "../../common/KebabMenuButton";
Expand All @@ -18,6 +19,7 @@ import { ToggleValue } from "../../common/Toggle/types";
import { Tooltip } from "../../common/Tooltip";
import { ChevronIcon } from "../../common/icons/ChevronIcon";
import { InfoCircleIcon } from "../../common/icons/InfoCircleIcon";
import { OpenTelemetryLogoSmallIcon } from "../../common/icons/OpenTelemetryLogoSmallIcon";
import { Direction } from "../../common/icons/types";
import { Description, Link } from "../styles";
import * as s from "./styles";
Expand All @@ -33,6 +35,7 @@ export const InsightCard = (props: InsightCardProps) => {
const [percentileViewMode, setPercentileViewMode] =
useState<number>(DEFAULT_PERCENTILE);
const [isRecalculatingStarted, setIsRecalculatingStarted] = useState(false);
const { scope } = useContext(ConfigContext);

const theme = useTheme();
const insightTypeInfo = getInsightTypeInfo(props.data.type);
Expand Down Expand Up @@ -121,103 +124,114 @@ export const InsightCard = (props: InsightCardProps) => {
: false;

return (
<Card
header={
<>
<>
<Card
showTitle={!!(props.title && !scope?.span)}
title={
<s.Title>
<s.InsightIconContainer>
{props.isRecent && (
<s.BadgeContainer>
<Badge />
</s.BadgeContainer>
<s.TitleIcon>
<OpenTelemetryLogoSmallIcon color="#6063F6" size={16} />
</s.TitleIcon>
<s.TitleText>{props.title}</s.TitleText>
</s.Title>
}
header={
<>
<s.Header>
<s.InsightIconContainer>
{props.isRecent && (
<s.BadgeContainer>
<Badge />
</s.BadgeContainer>
)}
{insightTypeInfo && (
<insightTypeInfo.icon color={insightIconColor} size={16} />
)}
</s.InsightIconContainer>
{insightTypeInfo?.label || props.data.type}
{insightTypeInfo?.description && (
<Tooltip title={<insightTypeInfo.description />}>
<s.InfoContainer>
<InfoCircleIcon color={"currentColor"} size={16} />
</s.InfoContainer>
</Tooltip>
)}
{insightTypeInfo && (
<insightTypeInfo.icon color={insightIconColor} size={16} />
</s.Header>
<s.Toolbar>
{isNew && <Tag type={"success"} value={"New"} />}
{props.isAsync && <s.AsyncBadge>Async</s.AsyncBadge>}
{props.stats && <s.Stats>{props.stats}</s.Stats>}
{(props.menuItems || props.data.isRecalculateEnabled) && (
<Popover
open={isKebabMenuOpen}
onOpenChange={setIsKebabMenuOpen}
placement={"bottom-start"}
>
<PopoverTrigger onClick={handleKebabMenuButtonToggle}>
<KebabMenuButton />
</PopoverTrigger>
<PopoverContent className={"Popover"} width={"max-content"}>
<Menu
items={[
...(props.data.isRecalculateEnabled
? [{ value: RECALCULATE, label: "Recalculate" }]
: []),
...(props.menuItems
? props.menuItems.map((x) => ({ value: x, label: x }))
: [])
]}
onSelect={handleKebabMenuItemSelect}
/>
</PopoverContent>
</Popover>
)}
</s.InsightIconContainer>
{insightTypeInfo?.label || props.data.type}
{insightTypeInfo?.description && (
<Tooltip title={<insightTypeInfo.description />}>
<s.InfoContainer>
<InfoCircleIcon color={"currentColor"} size={16} />
</s.InfoContainer>
</Tooltip>
)}
</s.Title>
<s.Toolbar>
{isNew && <Tag type={"success"} value={"New"} />}
{props.isAsync && <s.AsyncBadge>Async</s.AsyncBadge>}
{props.stats && <s.Stats>{props.stats}</s.Stats>}
{(props.menuItems || props.data.isRecalculateEnabled) && (
<Popover
open={isKebabMenuOpen}
onOpenChange={setIsKebabMenuOpen}
placement={"bottom-start"}
>
<PopoverTrigger onClick={handleKebabMenuButtonToggle}>
<KebabMenuButton />
</PopoverTrigger>
<PopoverContent className={"Popover"} width={"max-content"}>
<Menu
items={[
...(props.data.isRecalculateEnabled
? [{ value: RECALCULATE, label: "Recalculate" }]
: []),
...(props.menuItems
? props.menuItems.map((x) => ({ value: x, label: x }))
: [])
]}
onSelect={handleKebabMenuItemSelect}
{props.expandableContent && (
<s.ExpandButton onClick={handleExpandButtonClick}>
<ChevronIcon
color={theme.mode === "light" ? "#828797" : "#b9c2eb"}
direction={isExpanded ? Direction.UP : Direction.DOWN}
size={14}
/>
</PopoverContent>
</Popover>
</s.ExpandButton>
)}
</s.Toolbar>
</>
}
content={
<>
{props.onPercentileViewModeChange && (
<Toggle
options={PERCENTILES.map((percentile) => ({
value: percentile.percentile,
label: percentile.label
}))}
value={percentileViewMode}
onValueChange={handlePercentileToggleValueChange}
/>
)}
{props.data.actualStartTime &&
renderRecalculationBlock(
props.data.actualStartTime,
props.data.customStartTime,
isRecalculatingStarted
)}
{props.content && (
<s.ContentContainer>{props.content}</s.ContentContainer>
)}
{props.expandableContent && (
<s.ExpandButton onClick={handleExpandButtonClick}>
<ChevronIcon
color={theme.mode === "light" ? "#828797" : "#b9c2eb"}
direction={isExpanded ? Direction.UP : Direction.DOWN}
size={14}
/>
</s.ExpandButton>
<span>
<Link onClick={handleExpandButtonClick}>
Show {isExpanded ? "less" : "more"}
</Link>
</span>
)}
</s.Toolbar>
</>
}
content={
<>
{props.onPercentileViewModeChange && (
<Toggle
options={PERCENTILES.map((percentile) => ({
value: percentile.percentile,
label: percentile.label
}))}
value={percentileViewMode}
onValueChange={handlePercentileToggleValueChange}
/>
)}
{props.data.actualStartTime &&
renderRecalculationBlock(
props.data.actualStartTime,
props.data.customStartTime,
isRecalculatingStarted
{isExpanded && props.expandableContent && (
<s.ContentContainer>{props.expandableContent}</s.ContentContainer>
)}
{props.content && (
<s.ContentContainer>{props.content}</s.ContentContainer>
)}
{props.expandableContent && (
<span>
<Link onClick={handleExpandButtonClick}>
Show {isExpanded ? "less" : "more"}
</Link>
</span>
)}
{isExpanded && props.expandableContent && (
<s.ContentContainer>{props.expandableContent}</s.ContentContainer>
)}
</>
}
buttons={props.buttons}
/>
</>
}
buttons={props.buttons}
/>
</>
);
};
41 changes: 41 additions & 0 deletions src/components/Insights/InsightCard/styles.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,48 @@
import styled from "styled-components";
import { Link } from "../styles";

export const TitleIcon = styled.div`
display: flex;
`;

export const TitleText = styled.div`
fill: #a1b5ff;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
display: block;
`;

export const Title = styled.div`
border-radius: 4px 4px 0 0;
display: flex;
padding: 4px 12px;
align-items: center;
gap: 4px;
background: ${({ theme }) => {
switch (theme.mode) {
case "light":
return "#B9C0D4";
case "dark":
case "dark-jetbrains":
return "#28293E";
}
}};
color: ${({ theme }) => {
switch (theme.mode) {
case "light":
return "#002D61";
case "dark":
case "dark-jetbrains":
return "#a1b5ff;";
}
}};
font-size: 14px;
font-style: normal;
font-weight: 400;
`;

export const Header = styled.div`
display: flex;
gap: 4px;
align-items: center;
Expand Down
1 change: 1 addition & 0 deletions src/components/Insights/InsightCard/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export interface InsightCardProps {
menuItems?: string[];
stats?: string;
buttons?: ReactNode[];
title?: string;
onRecalculate: (
prefixedCodeObjectId: string,
insightType: InsightType
Expand Down
1 change: 1 addition & 0 deletions src/components/Insights/NPlusOneInsight/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export const NPlusOneInsight = (props: NPlusOneInsightProps) => {
return (
<InsightCard
data={props.insight}
title={props.insight.spanInfo?.displayName}
content={
<s.ContentContainer>
<Description>Check the following SELECT statement:</Description>
Expand Down
1 change: 1 addition & 0 deletions src/components/Insights/NoScalingIssueInsight/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export const NoScalingIssueInsight = (props: NoScalingIssueInsightProps) => {
return (
<InsightCard
key={props.insight.type}
title={props.insight.spanInfo?.displayName}
data={props.insight}
content={<div>This code is scaling well at concurrent executions</div>}
buttons={[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ export const PerformanceAtScaleInsight = (
<InsightCard
key={props.insight.type}
data={props.insight}
title={props.insight.spanInfo?.displayName}
content={
<div>
Run at{" "}
Expand Down
1 change: 1 addition & 0 deletions src/components/Insights/QueryOptimizationInsight/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export const QueryOptimizationInsight = (
return (
<InsightCard
data={props.insight}
title={props.insight.spanInfo?.displayName}
content={
<s.ContentContainer>
<Description>
Expand Down
Loading