diff --git a/frontend/src/pages/AlertDetails/AlertHeader/AlertHeader.tsx b/frontend/src/pages/AlertDetails/AlertHeader/AlertHeader.tsx
index f4ff7b933b..073b84382b 100644
--- a/frontend/src/pages/AlertDetails/AlertHeader/AlertHeader.tsx
+++ b/frontend/src/pages/AlertDetails/AlertHeader/AlertHeader.tsx
@@ -1,5 +1,6 @@
import './AlertHeader.styles.scss';
+import LineClampedText from 'periscope/components/LineClampedText/LineClampedText';
import { useAlertRule } from 'providers/Alert';
import { useEffect, useMemo } from 'react';
@@ -42,7 +43,9 @@ function AlertHeader({ alertDetails }: AlertHeaderProps): JSX.Element {
diff --git a/frontend/src/periscope/components/KeyValueLabel/KeyValueLabel.tsx b/frontend/src/periscope/components/KeyValueLabel/KeyValueLabel.tsx
index aa14dd6380..377c647a3f 100644
--- a/frontend/src/periscope/components/KeyValueLabel/KeyValueLabel.tsx
+++ b/frontend/src/periscope/components/KeyValueLabel/KeyValueLabel.tsx
@@ -1,18 +1,37 @@
import './KeyValueLabel.styles.scss';
-type KeyValueLabelProps = { badgeKey: string; badgeValue: string };
+import { Tooltip } from 'antd';
+
+import TrimmedText from '../TrimmedText/TrimmedText';
+
+type KeyValueLabelProps = {
+ badgeKey: string;
+ badgeValue: string;
+ maxCharacters?: number;
+};
export default function KeyValueLabel({
badgeKey,
badgeValue,
+ maxCharacters = 20,
}: KeyValueLabelProps): JSX.Element | null {
if (!badgeKey || !badgeValue) {
return null;
}
return (
-
{badgeKey}
-
{badgeValue}
+
+
+
+
+
+
+
+
);
}
+
+KeyValueLabel.defaultProps = {
+ maxCharacters: 20,
+};
diff --git a/frontend/src/periscope/components/LineClampedText/LineClampedText.styles.scss b/frontend/src/periscope/components/LineClampedText/LineClampedText.styles.scss
new file mode 100644
index 0000000000..644ddc480b
--- /dev/null
+++ b/frontend/src/periscope/components/LineClampedText/LineClampedText.styles.scss
@@ -0,0 +1,6 @@
+.line-clamped-text {
+ display: -webkit-box;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
diff --git a/frontend/src/periscope/components/LineClampedText/LineClampedText.tsx b/frontend/src/periscope/components/LineClampedText/LineClampedText.tsx
new file mode 100644
index 0000000000..6b90704b0c
--- /dev/null
+++ b/frontend/src/periscope/components/LineClampedText/LineClampedText.tsx
@@ -0,0 +1,52 @@
+import './LineClampedText.styles.scss';
+
+import { Tooltip } from 'antd';
+import { useEffect, useRef, useState } from 'react';
+
+function LineClampedText({
+ text,
+ lines,
+}: {
+ text: string;
+ lines?: number;
+}): JSX.Element {
+ const [isOverflowing, setIsOverflowing] = useState(false);
+ const textRef = useRef
(null);
+
+ useEffect(() => {
+ const checkOverflow = (): void => {
+ if (textRef.current) {
+ setIsOverflowing(
+ textRef.current.scrollHeight > textRef.current.clientHeight,
+ );
+ }
+ };
+
+ checkOverflow();
+ window.addEventListener('resize', checkOverflow);
+
+ return (): void => {
+ window.removeEventListener('resize', checkOverflow);
+ };
+ }, [text, lines]);
+
+ const content = (
+
+ {text}
+
+ );
+
+ return isOverflowing ? {content} : content;
+}
+
+LineClampedText.defaultProps = {
+ lines: 1,
+};
+
+export default LineClampedText;
diff --git a/frontend/src/periscope/components/TrimmedText/TrimmedText.tsx b/frontend/src/periscope/components/TrimmedText/TrimmedText.tsx
new file mode 100644
index 0000000000..10919f2e3f
--- /dev/null
+++ b/frontend/src/periscope/components/TrimmedText/TrimmedText.tsx
@@ -0,0 +1,30 @@
+import { Tooltip } from 'antd';
+import { useEffect, useState } from 'react';
+
+function TrimmedText({
+ text,
+ maxCharacters,
+}: {
+ text: string;
+ maxCharacters: number;
+}): JSX.Element {
+ const [displayText, setDisplayText] = useState(text);
+
+ useEffect(() => {
+ if (text.length > maxCharacters) {
+ setDisplayText(`${text.slice(0, maxCharacters)}...`);
+ } else {
+ setDisplayText(text);
+ }
+ }, [text, maxCharacters]);
+
+ return text.length > maxCharacters ? (
+
+ {displayText}
+
+ ) : (
+ {displayText}
+ );
+}
+
+export default TrimmedText;