From fa5fcafd83b2f8e99a3fb9f218249c363377e3c5 Mon Sep 17 00:00:00 2001 From: Ece Ozalp Date: Mon, 12 Jul 2021 13:12:57 -0400 Subject: [PATCH] [CTI] shortens large numbers on Dashboard Link Panel --- .../utils/shorten_count_into_string.test.ts | 38 +++++++++++++++++ .../common/utils/shorten_count_into_string.ts | 41 +++++++++++++++++++ .../threat_intel_panel_view.tsx | 5 ++- 3 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/common/utils/shorten_count_into_string.test.ts create mode 100644 x-pack/plugins/security_solution/public/common/utils/shorten_count_into_string.ts diff --git a/x-pack/plugins/security_solution/public/common/utils/shorten_count_into_string.test.ts b/x-pack/plugins/security_solution/public/common/utils/shorten_count_into_string.test.ts new file mode 100644 index 00000000000000..13699f5dc30607 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/utils/shorten_count_into_string.test.ts @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { shortenCountIntoString } from './shorten_count_into_string'; + +describe('utils', () => { + describe('shortenCountIntoString', () => { + it('should not change small numbers', () => { + expect(shortenCountIntoString(0)).toBe('0'); + expect(shortenCountIntoString(9999)).toBe('9999'); + }); + + it('should add K when appropriate', () => { + expect(shortenCountIntoString(10000)).toBe('10K'); + expect(shortenCountIntoString(109000)).toBe('109K'); + expect(shortenCountIntoString(109800)).toBe('109.8K'); + expect(shortenCountIntoString(109897)).toBe('109.8K'); + }); + + it('should add M when appropriate', () => { + expect(shortenCountIntoString(10000000)).toBe('10M'); + expect(shortenCountIntoString(109000000)).toBe('109M'); + expect(shortenCountIntoString(109800000)).toBe('109.8M'); + expect(shortenCountIntoString(109890000)).toBe('109.8M'); + }); + + it('should add B when appropriate', () => { + expect(shortenCountIntoString(10000000000)).toBe('10B'); + expect(shortenCountIntoString(109000000000)).toBe('109B'); + expect(shortenCountIntoString(109800000000)).toBe('109.8B'); + expect(shortenCountIntoString(109890000000)).toBe('109.8B'); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/common/utils/shorten_count_into_string.ts b/x-pack/plugins/security_solution/public/common/utils/shorten_count_into_string.ts new file mode 100644 index 00000000000000..5f4667ada36c57 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/utils/shorten_count_into_string.ts @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +/* +10000 to 10K +10100 to 10.1K +1000000 to 1M +1000000000 to 1B +*/ +export const shortenCountIntoString = (count: number): string => { + if (count < 10000) { + return count.toString(); + } + const si = [ + { v: 1e3, s: 'K' }, + { v: 1e6, s: 'M' }, + { v: 1e9, s: 'B' }, + { v: 1e12, s: 'T' }, + { v: 1e15, s: 'P' }, + { v: 1e18, s: 'E' }, + ]; + let i; + for (i = si.length - 1; i > 0; i--) { + if (count >= si[i].v) { + break; + } + } + + return ( + toFixedWithoutRounding(count / si[i].v, 1).replace(/\.0+$|(\.[0-9]*[1-9])0+$/, '$1') + si[i].s + ); +}; + +const toFixedWithoutRounding = (n: number, p: number) => { + const result = n.toFixed(p); + return +result <= n ? result : (+result - Math.pow(0.1, p)).toFixed(p); +}; diff --git a/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/threat_intel_panel_view.tsx b/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/threat_intel_panel_view.tsx index b34f6e657d39a9..c9e05d03ff8752 100644 --- a/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/threat_intel_panel_view.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/threat_intel_panel_view.tsx @@ -25,6 +25,7 @@ import { CtiListItem } from '../../containers/overview_cti_links/helpers'; import { useKibana } from '../../../common/lib/kibana'; import { CtiInnerPanel } from './cti_inner_panel'; import * as i18n from './translations'; +import { shortenCountIntoString } from '../../../common/utils/shorten_count_into_string'; const DashboardLink = styled.li` margin: 0 ${({ theme }) => theme.eui.paddingSizes.s} 0 ${({ theme }) => theme.eui.paddingSizes.m}; @@ -84,7 +85,7 @@ export const ThreatIntelPanelView: React.FC = ({ () => ( @@ -160,7 +161,7 @@ export const ThreatIntelPanelView: React.FC = ({ justifyContent="flexEnd" > - {count} + {shortenCountIntoString(count)} {path ? (