diff --git a/src/components/Dashboard/NewReport/Chart/ServiceTile/TooltipKeyValue/styles.ts b/src/components/Dashboard/NewReport/Chart/ServiceTile/TooltipKeyValue/styles.ts index 9fc3c73c4..9b62cd90c 100644 --- a/src/components/Dashboard/NewReport/Chart/ServiceTile/TooltipKeyValue/styles.ts +++ b/src/components/Dashboard/NewReport/Chart/ServiceTile/TooltipKeyValue/styles.ts @@ -10,5 +10,6 @@ export const Container = styled.div` `; export const Label = styled.span` + text-transform: capitalize; color: ${({ theme }) => theme.colors.v3.text.secondary}; `; diff --git a/src/components/Dashboard/NewReport/Chart/ServiceTile/index.tsx b/src/components/Dashboard/NewReport/Chart/ServiceTile/index.tsx index 907ead5ae..c1564efec 100644 --- a/src/components/Dashboard/NewReport/Chart/ServiceTile/index.tsx +++ b/src/components/Dashboard/NewReport/Chart/ServiceTile/index.tsx @@ -10,7 +10,8 @@ const getFormattedNumber = (viewMode: ReportTimeMode, value: number) => export const ServiceTile = ({ name, criticalIssuesCount, - impactScore, + scoreCriterion, + score, severity, viewMode, onIssuesClick: onSeeIssuesClick @@ -19,7 +20,7 @@ export const ServiceTile = ({ viewMode, criticalIssuesCount ); - const formattedImpactScore = getFormattedNumber(viewMode, impactScore); + const formattedScore = getFormattedNumber(viewMode, score); return ( {name} - + {formattedCriticalIssuesCount} - - {formattedImpactScore} + + {formattedScore} } > onSeeIssuesClick && onSeeIssuesClick(name)}> - {formattedCriticalIssuesCount} | {formattedImpactScore} + {formattedCriticalIssuesCount} | {formattedScore} diff --git a/src/components/Dashboard/NewReport/Chart/ServiceTile/types.ts b/src/components/Dashboard/NewReport/Chart/ServiceTile/types.ts index acdf1c42f..875e0373c 100644 --- a/src/components/Dashboard/NewReport/Chart/ServiceTile/types.ts +++ b/src/components/Dashboard/NewReport/Chart/ServiceTile/types.ts @@ -1,10 +1,12 @@ import { Severity } from "../../MetricsTable/types"; import { ReportTimeMode } from "../../ReportHeader/types"; +import { ScoreCriterion } from "../../types"; export interface ServiceTileProps { name: string; criticalIssuesCount: number; - impactScore: number; + scoreCriterion: ScoreCriterion; + score: number; severity: Severity; viewMode: ReportTimeMode; onIssuesClick?: (service: string) => void; diff --git a/src/components/Dashboard/NewReport/Chart/index.tsx b/src/components/Dashboard/NewReport/Chart/index.tsx index 5ef58b8e7..f7991b65b 100644 --- a/src/components/Dashboard/NewReport/Chart/index.tsx +++ b/src/components/Dashboard/NewReport/Chart/index.tsx @@ -11,7 +11,11 @@ import { ServiceTile } from "./ServiceTile"; import * as s from "./styles"; import { ChartProps } from "./types"; -export const Chart = ({ data, onServiceSelected }: ChartProps) => { +export const Chart = ({ + data, + onServiceSelected, + scoreCriterion +}: ChartProps) => { const { width, height, observe } = useDimensions(); const viewMode: ReportTimeMode = data.some((service) => @@ -20,34 +24,27 @@ export const Chart = ({ data, onServiceSelected }: ChartProps) => { ? "changes" : "baseline"; - const transformedData = data.map((service) => ({ - ...service, - impact: Math.round(service.impact * 100) - })); - const handSeeIssuesClick = (service: string) => { sendUserActionTrackingEvent(trackingEvents.HEATMAP_SEE_ISSUES_LINK_CLICKED); onServiceSelected(service); }; - const minImpactScore = Math.min(...transformedData.map((x) => x.impact)); - const maxImpactScore = Math.max(...transformedData.map((x) => x.impact)); + const minScore = Math.min(...data.map((x) => x[scoreCriterion])); + const maxScore = Math.max(...data.map((x) => x[scoreCriterion])); - const chartData: Input[] = transformedData.map((service) => { - const severity = getSeverity( - minImpactScore, - maxImpactScore, - service.impact - ); + const chartData: Input[] = data.map((service) => { + const score = service[scoreCriterion]; + const severity = getSeverity(minScore, maxScore, score); return { id: service.key.service, - value: service.impact, + value: service[scoreCriterion], content: ( void; + scoreCriterion: ScoreCriterion; } diff --git a/src/components/Dashboard/NewReport/MetricsTable/index.tsx b/src/components/Dashboard/NewReport/MetricsTable/index.tsx index b1e974837..b0ccd1485 100644 --- a/src/components/Dashboard/NewReport/MetricsTable/index.tsx +++ b/src/components/Dashboard/NewReport/MetricsTable/index.tsx @@ -13,17 +13,19 @@ import { sendUserActionTrackingEvent } from "../../../../utils/actions/sendUserA import { SortIcon } from "../../../common/icons/16px/SortIcon"; import { SORTING_ORDER } from "../../../common/SortingSelector/types"; import { trackingEvents } from "../tracking"; -import { ServiceData } from "../types"; +import { ScoreCriterion, ServiceData } from "../types"; import { getSeverity } from "../utils"; import * as s from "./styles"; import { ColumnMeta, MetricsTableProps, Severity } from "./types"; -const sortImpactFn: SortingFn = (rowA, rowB) => { - const impactA = rowA.original.impact; - const impactB = rowB.original.impact; +const getSortScoreFn = + (scoreCriterion: ScoreCriterion): SortingFn => + (rowA, rowB) => { + const scoreA = rowA.original[scoreCriterion]; + const scoreB = rowB.original[scoreCriterion]; - return impactA - impactB; -}; + return scoreA - scoreB; + }; const sortIssuesFn: SortingFn = (rowA, rowB) => { const issuesA = rowA.original.issues; @@ -67,11 +69,12 @@ const IssuesLink = ({ export const MetricsTable = ({ data, showSign, - onServiceSelected + onServiceSelected, + scoreCriterion }: MetricsTableProps) => { const columnHelper = createColumnHelper(); - const minImpact = Math.min(...data.map((x) => x.impact)); - const maxImpact = Math.max(...data.map((x) => x.impact)); + const minScore = Math.min(...data.map((x) => x[scoreCriterion])); + const maxScore = Math.max(...data.map((x) => x[scoreCriterion])); const handleSeeIssuesLinkClick = (service: string, source: string) => { onServiceSelected(service); @@ -107,25 +110,28 @@ export const MetricsTable = ({ enableSorting: true }), columnHelper.accessor((row) => row, { - id: "impact", - header: "Impact", + id: "score", + header: scoreCriterion, cell: (info) => ( - handleSeeIssuesLinkClick(info.getValue().key.service, "impact") + handleSeeIssuesLinkClick( + info.getValue().key.service, + scoreCriterion + ) } > - {Math.round(info.getValue().impact * 100)} + {info.getValue()[scoreCriterion]} ), - sortingFn: sortImpactFn, + sortingFn: getSortScoreFn(scoreCriterion), enableSorting: true, meta: { contentAlign: "center" } }), columnHelper.accessor( - (row) => getSeverity(minImpact, maxImpact, row.impact), + (row) => getSeverity(minScore, maxScore, row[scoreCriterion]), { header: "Rank", id: "rank", @@ -133,7 +139,7 @@ export const MetricsTable = ({ cell: (info) => { return info.getValue(); }, - sortingFn: sortImpactFn, + sortingFn: getSortScoreFn(scoreCriterion), meta: { contentAlign: "center" } diff --git a/src/components/Dashboard/NewReport/MetricsTable/mockData.ts b/src/components/Dashboard/NewReport/MetricsTable/mockData.ts index 7b100fdcb..e944e1ce8 100644 --- a/src/components/Dashboard/NewReport/MetricsTable/mockData.ts +++ b/src/components/Dashboard/NewReport/MetricsTable/mockData.ts @@ -4,6 +4,7 @@ export const mockedReport: ServiceMetricsReport = { reports: [ { impact: 100.123123, + criticality: 100.123123, key: { environment: "TEST", service: "Transactions", @@ -13,6 +14,7 @@ export const mockedReport: ServiceMetricsReport = { }, { impact: 50, + criticality: 50, key: { environment: "TEST", service: "API", @@ -22,6 +24,7 @@ export const mockedReport: ServiceMetricsReport = { }, { impact: 1, + criticality: 1, key: { environment: "TEST", service: "Orders", @@ -31,6 +34,7 @@ export const mockedReport: ServiceMetricsReport = { }, { impact: 120, + criticality: 120, key: { environment: "TEST", service: "Users", @@ -40,6 +44,7 @@ export const mockedReport: ServiceMetricsReport = { }, { impact: 120, + criticality: 120, key: { environment: "TEST", service: "Users1", @@ -49,6 +54,7 @@ export const mockedReport: ServiceMetricsReport = { }, { impact: 70, + criticality: 70, key: { environment: "TEST", service: "Users2", @@ -58,6 +64,7 @@ export const mockedReport: ServiceMetricsReport = { }, { impact: 99.1231, + criticality: 99.1231, key: { environment: "TEST", service: "Users3", diff --git a/src/components/Dashboard/NewReport/MetricsTable/styles.ts b/src/components/Dashboard/NewReport/MetricsTable/styles.ts index 404c95d93..d2d076ea8 100644 --- a/src/components/Dashboard/NewReport/MetricsTable/styles.ts +++ b/src/components/Dashboard/NewReport/MetricsTable/styles.ts @@ -50,6 +50,7 @@ export const TableHeaderCellContent = styled(TableCellContent)` gap: 4px; color: ${({ theme }) => theme.colors.v3.text.tertiary}; ${({ onClick }) => (onClick ? "cursor: pointer;" : "")} + text-transform: capitalize; `; export const TableBodyRow = styled.tr` diff --git a/src/components/Dashboard/NewReport/MetricsTable/types.ts b/src/components/Dashboard/NewReport/MetricsTable/types.ts index e09b054fe..560369358 100644 --- a/src/components/Dashboard/NewReport/MetricsTable/types.ts +++ b/src/components/Dashboard/NewReport/MetricsTable/types.ts @@ -1,9 +1,10 @@ -import { ServiceData } from "../types"; +import { ScoreCriterion, ServiceData } from "../types"; export interface MetricsTableProps { data: ServiceData[]; showSign: boolean; onServiceSelected: (name: string) => void; + scoreCriterion: ScoreCriterion; } export type ContentAlignment = "left" | "center" | "right"; diff --git a/src/components/Dashboard/NewReport/index.tsx b/src/components/Dashboard/NewReport/index.tsx index 49e83868e..ca211e072 100644 --- a/src/components/Dashboard/NewReport/index.tsx +++ b/src/components/Dashboard/NewReport/index.tsx @@ -1,4 +1,7 @@ import { useLayoutEffect, useState } from "react"; +import { getFeatureFlagValue } from "../../../featureFlags"; +import { useConfigSelector } from "../../../store/config/useConfigSelector"; +import { FeatureFlag } from "../../../types"; import { changeScope } from "../../../utils/actions/changeScope"; import { DigmaLogoIcon } from "../../common/icons/16px/DigmaLogoIcon"; import { SCOPE_CHANGE_EVENTS } from "../../Main/types"; @@ -21,6 +24,12 @@ export const NewReport = () => { const [query, setQuery] = useState(DefaultQuery); const { data } = useReportsData(query); const [viewMode, setViewMode] = useState("table"); + const { backendInfo } = useConfigSelector(); + const isCriticalityEnabled = getFeatureFlagValue( + backendInfo, + FeatureFlag.IS_METRICS_REPORT_CRITICALITY_ENABLED + ); + const scoreCriterion = isCriticalityEnabled ? "criticality" : "impact"; useLayoutEffect(() => { window.sendMessageToDigma({ @@ -50,6 +59,10 @@ export const NewReport = () => { }; const serviceData = (query?.services.length > 0 ? data?.reports : null) ?? []; + const transformedData = serviceData.map((service) => ({ + ...service, + [scoreCriterion]: Math.round(service[scoreCriterion] * 100) + })); return ( @@ -62,13 +75,18 @@ export const NewReport = () => { /> {viewMode === "table" && ( )} {viewMode === "treemap" && ( - + )} diff --git a/src/components/Dashboard/NewReport/types.ts b/src/components/Dashboard/NewReport/types.ts index fe1126341..564512af8 100644 --- a/src/components/Dashboard/NewReport/types.ts +++ b/src/components/Dashboard/NewReport/types.ts @@ -30,8 +30,11 @@ export interface ServiceData { }; issues: number; impact: number; + criticality: number; } export interface ServiceMetricsReport { reports: ServiceData[]; } + +export type ScoreCriterion = "impact" | "criticality"; diff --git a/src/components/common/TreeMap/TreeMap.stories.tsx b/src/components/common/TreeMap/TreeMap.stories.tsx index 8908e6cbd..abe7151c9 100644 --- a/src/components/common/TreeMap/TreeMap.stories.tsx +++ b/src/components/common/TreeMap/TreeMap.stories.tsx @@ -29,7 +29,8 @@ export const Default: Story = { @@ -42,7 +43,8 @@ export const Default: Story = { @@ -55,7 +57,8 @@ export const Default: Story = { @@ -68,7 +71,8 @@ export const Default: Story = { @@ -81,7 +85,8 @@ export const Default: Story = { diff --git a/src/featureFlags.ts b/src/featureFlags.ts index 87879db68..4d868d83b 100644 --- a/src/featureFlags.ts +++ b/src/featureFlags.ts @@ -15,7 +15,8 @@ export const featureFlagMinBackendVersions: Record = { [FeatureFlag.ARE_ISSUES_SERVICES_FILTERS_ENABLED]: "0.3.103", [FeatureFlag.ARE_EXTENDED_ASSETS_FILTERS_ENABLED]: "0.3.107", [FeatureFlag.IS_NEW_IMPACT_SCORE_CALCULATION_ENABLED]: "0.3.107", - [FeatureFlag.IS_METRICS_REPORT_ENABLED]: "0.3.120-alpha.15" + [FeatureFlag.IS_METRICS_REPORT_ENABLED]: "0.3.120-alpha.15", + [FeatureFlag.IS_METRICS_REPORT_CRITICALITY_ENABLED]: "0.3.121" }; export const getFeatureFlagValue = ( diff --git a/src/types.ts b/src/types.ts index 2120ae17a..e3790e4ce 100644 --- a/src/types.ts +++ b/src/types.ts @@ -17,7 +17,8 @@ export enum FeatureFlag { ARE_ISSUES_SERVICES_FILTERS_ENABLED, ARE_EXTENDED_ASSETS_FILTERS_ENABLED, IS_NEW_IMPACT_SCORE_CALCULATION_ENABLED, - IS_METRICS_REPORT_ENABLED + IS_METRICS_REPORT_ENABLED, + IS_METRICS_REPORT_CRITICALITY_ENABLED } export enum InsightType {