From d6750015b6fb347e9aac1e5fec329f8789cd59af Mon Sep 17 00:00:00 2001 From: Kyrylo Shmidt Date: Wed, 6 Mar 2024 16:14:51 +0100 Subject: [PATCH 1/3] Add insight status --- .../EndpointNPlusOneInsight/mockData.ts | 6 ++- .../InsightHeader/InisghtHeader.stories.tsx | 3 +- .../InsightStatusBadge.stories.tsx | 39 +++++++++++++++++++ .../getInsightStatusInfo.ts | 35 +++++++++++++++++ .../InsightStatusBadge/index.tsx | 21 ++++++++++ .../InsightStatusBadge/styles.ts | 29 ++++++++++++++ .../InsightHeader/InsightStatusBadge/types.ts | 9 +++++ .../InsightCard/InsightHeader/index.tsx | 12 +++--- .../InsightCard/InsightHeader/styles.ts | 22 +---------- .../common/InsightCard/InsightHeader/types.ts | 3 +- .../Insights/common/InsightCard/index.tsx | 2 +- src/components/Insights/types.ts | 8 ++++ 12 files changed, 155 insertions(+), 34 deletions(-) create mode 100644 src/components/Insights/common/InsightCard/InsightHeader/InsightStatusBadge/InsightStatusBadge.stories.tsx create mode 100644 src/components/Insights/common/InsightCard/InsightHeader/InsightStatusBadge/getInsightStatusInfo.ts create mode 100644 src/components/Insights/common/InsightCard/InsightHeader/InsightStatusBadge/index.tsx create mode 100644 src/components/Insights/common/InsightCard/InsightHeader/InsightStatusBadge/styles.ts create mode 100644 src/components/Insights/common/InsightCard/InsightHeader/InsightStatusBadge/types.ts diff --git a/src/components/Insights/EndpointNPlusOneInsight/mockData.ts b/src/components/Insights/EndpointNPlusOneInsight/mockData.ts index bf1c8d8b4..cdf4a4fb4 100644 --- a/src/components/Insights/EndpointNPlusOneInsight/mockData.ts +++ b/src/components/Insights/EndpointNPlusOneInsight/mockData.ts @@ -2,7 +2,8 @@ import { InsightType } from "../../../types"; import { EndpointSuspectedNPlusOneInsight, InsightCategory, - InsightScope + InsightScope, + InsightStatus } from "../types"; export const mockedEndpointNPlusOneInsight: EndpointSuspectedNPlusOneInsight = { @@ -87,5 +88,6 @@ export const mockedEndpointNPlusOneInsight: EndpointSuspectedNPlusOneInsight = { prefixedCodeObjectId: "method:org.springframework.samples.petclinic.sample.SampleInsightsController$_$genNPlusOneWithoutInternalSpan", customStartTime: null, - actualStartTime: "2023-06-16T10:30:33.027Z" + actualStartTime: "2023-06-16T10:30:33.027Z", + status: InsightStatus.Active }; diff --git a/src/components/Insights/common/InsightCard/InsightHeader/InisghtHeader.stories.tsx b/src/components/Insights/common/InsightCard/InsightHeader/InisghtHeader.stories.tsx index a20987bf2..b34b55cb6 100644 --- a/src/components/Insights/common/InsightCard/InsightHeader/InisghtHeader.stories.tsx +++ b/src/components/Insights/common/InsightCard/InsightHeader/InisghtHeader.stories.tsx @@ -20,7 +20,6 @@ export const Default: Story = { importance: 3, insightType: "HotSpot", isNew: true, - isAsync: true, - isActive: true + isAsync: true } }; diff --git a/src/components/Insights/common/InsightCard/InsightHeader/InsightStatusBadge/InsightStatusBadge.stories.tsx b/src/components/Insights/common/InsightCard/InsightHeader/InsightStatusBadge/InsightStatusBadge.stories.tsx new file mode 100644 index 000000000..f21f88170 --- /dev/null +++ b/src/components/Insights/common/InsightCard/InsightHeader/InsightStatusBadge/InsightStatusBadge.stories.tsx @@ -0,0 +1,39 @@ +import { Meta, StoryObj } from "@storybook/react"; +import { InsightStatusBadge } from "."; +import { InsightStatus } from "../../../../types"; + +// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction +const meta: Meta = { + title: "Insights/common/InsightCard/InsightHeader/InsightStatusBadge", + component: InsightStatusBadge, + 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 Active: Story = { + args: { + status: InsightStatus.Active + } +}; + +export const Evaluating: Story = { + args: { + status: InsightStatus.InEvaluation + } +}; +export const PossiblyFixed: Story = { + args: { + status: InsightStatus.PossiblyFixed + } +}; +export const Regression: Story = { + args: { + status: InsightStatus.Regression + } +}; diff --git a/src/components/Insights/common/InsightCard/InsightHeader/InsightStatusBadge/getInsightStatusInfo.ts b/src/components/Insights/common/InsightCard/InsightHeader/InsightStatusBadge/getInsightStatusInfo.ts new file mode 100644 index 000000000..ad305c3ea --- /dev/null +++ b/src/components/Insights/common/InsightCard/InsightHeader/InsightStatusBadge/getInsightStatusInfo.ts @@ -0,0 +1,35 @@ +import { DefaultTheme } from "styled-components/dist/types"; +import { InsightStatus } from "../../../../types"; + +interface InsightStatusInfo { + label: string; + color: string; +} + +export const getInsightStatusInfo = ( + status: InsightStatus, + theme: DefaultTheme +): InsightStatusInfo | undefined => { + switch (status) { + case InsightStatus.Active: + return { + label: "Active", + color: theme.colors.v3.status.success + }; + case InsightStatus.InEvaluation: + return { + label: "Evaluating", + color: theme.colors.v3.status.medium + }; + case InsightStatus.PossiblyFixed: + return { + label: "Possibly Fixed", + color: theme.colors.v3.status.low + }; + case InsightStatus.Regression: + return { + label: "Regression", + color: theme.colors.v3.status.backgroundLow + }; + } +}; diff --git a/src/components/Insights/common/InsightCard/InsightHeader/InsightStatusBadge/index.tsx b/src/components/Insights/common/InsightCard/InsightHeader/InsightStatusBadge/index.tsx new file mode 100644 index 000000000..96c55194d --- /dev/null +++ b/src/components/Insights/common/InsightCard/InsightHeader/InsightStatusBadge/index.tsx @@ -0,0 +1,21 @@ +import { useTheme } from "styled-components"; +import { getInsightStatusInfo } from "./getInsightStatusInfo"; +import * as s from "./styles"; +import { InsightStatusBadgeProps } from "./types"; + +export const InsightStatusBadge = (props: InsightStatusBadgeProps) => { + const theme = useTheme(); + + const statusInfo = getInsightStatusInfo(props.status, theme); + + if (statusInfo) { + return ( + + + {statusInfo.label} + + ); + } + + return null; +}; diff --git a/src/components/Insights/common/InsightCard/InsightHeader/InsightStatusBadge/styles.ts b/src/components/Insights/common/InsightCard/InsightHeader/InsightStatusBadge/styles.ts new file mode 100644 index 000000000..94652267f --- /dev/null +++ b/src/components/Insights/common/InsightCard/InsightHeader/InsightStatusBadge/styles.ts @@ -0,0 +1,29 @@ +import styled, { css } from "styled-components"; +import { footnoteRegularTypography } from "../../../../../common/App/typographies"; +import { getInsightStatusInfo } from "./getInsightStatusInfo"; +import { IndicatorProps } from "./types"; + +export const Container = styled.div` + ${footnoteRegularTypography} + + display: flex; + align-items: center; + gap: 4px; + color: ${({ theme }) => theme.colors.v3.text.secondary}; + padding: 4px 0; +`; + +export const Indicator = styled.div` + border-radius: 50%; + width: 6px; + height: 6px; + ${({ theme, $status }) => { + const statusInfo = getInsightStatusInfo($status, theme); + + return statusInfo + ? css` + background: ${statusInfo.color}; + ` + : ""; + }} +`; diff --git a/src/components/Insights/common/InsightCard/InsightHeader/InsightStatusBadge/types.ts b/src/components/Insights/common/InsightCard/InsightHeader/InsightStatusBadge/types.ts new file mode 100644 index 000000000..1bf542b98 --- /dev/null +++ b/src/components/Insights/common/InsightCard/InsightHeader/InsightStatusBadge/types.ts @@ -0,0 +1,9 @@ +import { InsightStatus } from "../../../../types"; + +export interface InsightStatusBadgeProps { + status: InsightStatus; +} + +export interface IndicatorProps { + $status: InsightStatus; +} diff --git a/src/components/Insights/common/InsightCard/InsightHeader/index.tsx b/src/components/Insights/common/InsightCard/InsightHeader/index.tsx index b72dd0ce3..fd45b7ab8 100644 --- a/src/components/Insights/common/InsightCard/InsightHeader/index.tsx +++ b/src/components/Insights/common/InsightCard/InsightHeader/index.tsx @@ -13,9 +13,12 @@ import { Tag } from "../../../../common/v3/Tag"; import { TagType } from "../../../../common/v3/Tag/types"; import { Tooltip } from "../../../../common/v3/Tooltip"; import { AsyncTag } from "./AsyncTag"; +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"; @@ -76,7 +79,7 @@ export const InsightHeader = (props: InsightHeaderProps) => { )} - {props.criticality > 0.8 && ( + {props.criticality > HIGH_CRITICALITY_THRESHOLD && ( @@ -85,12 +88,7 @@ export const InsightHeader = (props: InsightHeaderProps) => { )} {props.isAsync && } {props.isNew && } - {props.isActive && ( - - - Active - - )} + {props.status && } {!config.scope?.span && props.spanInfo && ( diff --git a/src/components/Insights/common/InsightCard/InsightHeader/styles.ts b/src/components/Insights/common/InsightCard/InsightHeader/styles.ts index 4d9672e21..c5e186a24 100644 --- a/src/components/Insights/common/InsightCard/InsightHeader/styles.ts +++ b/src/components/Insights/common/InsightCard/InsightHeader/styles.ts @@ -1,8 +1,5 @@ import styled from "styled-components"; -import { - bodyMediumTypography, - footnoteRegularTypography -} from "../../../../common/App/typographies"; +import { bodyMediumTypography } from "../../../../common/App/typographies"; export const Container = styled.div` display: flex; @@ -49,20 +46,3 @@ export const WarningTriangleContainer = styled.div` display: flex; color: ${({ theme }) => theme.colors.v3.status.high}; `; - -export const Active = styled.div` - ${footnoteRegularTypography} - - display: flex; - align-items: center; - gap: 4px; - color: ${({ theme }) => theme.colors.v3.text.secondary}; - padding: 4px; -`; - -export const Indicator = styled.div` - border-radius: 50%; - width: 6px; - height: 6px; - background: ${({ theme }) => theme.colors.v3.status.success}; -`; diff --git a/src/components/Insights/common/InsightCard/InsightHeader/types.ts b/src/components/Insights/common/InsightCard/InsightHeader/types.ts index 6afed02bb..537e2d317 100644 --- a/src/components/Insights/common/InsightCard/InsightHeader/types.ts +++ b/src/components/Insights/common/InsightCard/InsightHeader/types.ts @@ -1,8 +1,8 @@ import { SpanInfo } from "../../../../../types"; +import { InsightStatus } from "../../../types"; export interface InsightHeaderProps { insightType: string; - isActive?: boolean; tags?: []; importance: number; isAsync?: boolean; @@ -10,4 +10,5 @@ export interface InsightHeaderProps { criticality: number; spanInfo?: SpanInfo | null; onSpanLinkClick: (spanCodeObjectId: string) => void; + status?: InsightStatus; } diff --git a/src/components/Insights/common/InsightCard/index.tsx b/src/components/Insights/common/InsightCard/index.tsx index ba112773d..68c161a62 100644 --- a/src/components/Insights/common/InsightCard/index.tsx +++ b/src/components/Insights/common/InsightCard/index.tsx @@ -209,7 +209,7 @@ export const InsightCard = (props: InsightCardProps) => { spanInfo={ isSpanInsight(props.insight) ? props.insight.spanInfo : undefined } - isActive={props.isActive} + status={props.insight.status} isNew={isNew} isAsync={props.isAsync} insightType={props.insight.type} diff --git a/src/components/Insights/types.ts b/src/components/Insights/types.ts index bb7182e8f..07d6a384b 100644 --- a/src/components/Insights/types.ts +++ b/src/components/Insights/types.ts @@ -160,6 +160,13 @@ export interface CodeObjectDecorator { title: string; } +export enum InsightStatus { + Active = "Active", + InEvaluation = "InEvaluation", + PossiblyFixed = "PossiblyFixed", + Regression = "Regression" +} + export interface CodeObjectInsight extends Insight { shortDisplayInfo: { title: string; @@ -189,6 +196,7 @@ export interface CodeObjectInsight extends Insight { ticketLink: string | null; id: string; sourceSpanCodeObjectInsight: string; + status?: InsightStatus; } export interface SpanInsight extends CodeObjectInsight { From 99d59e65855aa143f3413d3af23c319cff3f162a Mon Sep 17 00:00:00 2001 From: Kyrylo Shmidt Date: Wed, 6 Mar 2024 16:18:02 +0100 Subject: [PATCH 2/3] Rename Recalculate button --- src/components/Insights/common/InsightCard/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Insights/common/InsightCard/index.tsx b/src/components/Insights/common/InsightCard/index.tsx index 68c161a62..369ab7c54 100644 --- a/src/components/Insights/common/InsightCard/index.tsx +++ b/src/components/Insights/common/InsightCard/index.tsx @@ -115,11 +115,11 @@ export const InsightCard = (props: InsightCardProps) => { props.insight.isRecalculateEnabled && buttonsToRender.push({ - tooltip: "Recalculate", + tooltip: "Recheck", button: (btnProps) => (