diff --git a/packages/manager/src/features/CloudPulse/Alerts/AlertsDetail/AlertDetailCriteria.test.tsx b/packages/manager/src/features/CloudPulse/Alerts/AlertsDetail/AlertDetailCriteria.test.tsx
index 975b863186a..0f6a6f5752a 100644
--- a/packages/manager/src/features/CloudPulse/Alerts/AlertsDetail/AlertDetailCriteria.test.tsx
+++ b/packages/manager/src/features/CloudPulse/Alerts/AlertsDetail/AlertDetailCriteria.test.tsx
@@ -1,15 +1,32 @@
import React from 'react';
-import { alertFactory } from 'src/factories';
+import {
+ alertDimensionsFactory,
+ alertFactory,
+ alertRulesFactory,
+} from 'src/factories';
import { renderWithTheme } from 'src/utilities/testHelpers';
-import { operators } from '../constants';
+import { metricOperatorTypeMap } from '../constants';
import { convertSecondsToMinutes } from '../Utils/utils';
import { AlertDetailCriteria } from './AlertDetailCriteria';
describe('AlertDetailCriteria component tests', () => {
it('should render the alert detail criteria successfully on correct inputs', () => {
- const alertDetails = alertFactory.build();
+ const alertDetails = alertFactory.build({
+ rule_criteria: {
+ rules: [
+ ...alertRulesFactory.buildList(2, {
+ aggregation_type: 'avg',
+ dimension_filters: alertDimensionsFactory.buildList(2),
+ label: 'CPU Usage',
+ metric: 'cpu_usage',
+ operator: 'gt',
+ unit: 'bytes',
+ }),
+ ],
+ },
+ });
const { getAllByText, getByText } = renderWithTheme(
);
@@ -19,7 +36,8 @@ describe('AlertDetailCriteria component tests', () => {
expect(getByText('Criteria')).toBeInTheDocument();
expect(getAllByText('Average').length).toBe(2);
expect(getAllByText('CPU Usage').length).toBe(2);
- expect(getAllByText(operators['gt']).length).toBe(2);
+ expect(getAllByText('bytes').length).toBe(2);
+ expect(getAllByText(metricOperatorTypeMap['gt']).length).toBe(2);
const {
evaluation_period_seconds,
diff --git a/packages/manager/src/features/CloudPulse/Alerts/AlertsDetail/DisplayAlertDetailChips.tsx b/packages/manager/src/features/CloudPulse/Alerts/AlertsDetail/DisplayAlertDetailChips.tsx
index 0acebc710f9..b85f463e429 100644
--- a/packages/manager/src/features/CloudPulse/Alerts/AlertsDetail/DisplayAlertDetailChips.tsx
+++ b/packages/manager/src/features/CloudPulse/Alerts/AlertsDetail/DisplayAlertDetailChips.tsx
@@ -2,6 +2,7 @@ import { Typography } from '@linode/ui';
import { Grid, useTheme } from '@mui/material';
import React from 'react';
+import { getAlertChipBorderRadius } from '../Utils/utils';
import { StyledAlertChip } from './AlertDetail';
export interface AlertDimensionsProp {
@@ -42,7 +43,7 @@ export const DisplayAlertDetailChips = React.memo(
values: values,
} = props;
- const iterables: string[][] = Array.isArray(values)
+ const chipValues: string[][] = Array.isArray(values)
? values.every(Array.isArray)
? values
: [values]
@@ -50,33 +51,12 @@ export const DisplayAlertDetailChips = React.memo(
const theme = useTheme();
- /**
- * @param index The index of the list of chips that we are rendering
- * @param length The length of the iteration so far
- * @returns The border radius to be applied on chips based on the parameters
- */
- const getAlertChipBorderRadius = (
- index: number,
- length: number
- ): string => {
- if (!mergeChips || length === 1) {
- return theme.spacing(0.3);
- }
- if (index === 0) {
- return `${theme.spacing(0.3)} 0 0 ${theme.spacing(0.3)}`;
- }
- if (index === length - 1) {
- return `0 ${theme.spacing(0.3)} ${theme.spacing(0.3)} 0`;
- }
- return '0';
- };
-
return (
- {iterables.map((value, idx) => (
-
+ {chipValues.map((value, index) => (
+
- {idx === 0 && (
+ {index === 0 && (
0 && (
[
- label,
- operatorLabel[operator],
- value,
- ])}
+ values={dimensionFilters.map(
+ ({
+ label: dimensionLabel,
+ operator: dimensionOperator,
+ value,
+ }) => [
+ dimensionLabel,
+ dimensionOperatorTypeMap[dimensionOperator],
+ value,
+ ]
+ )}
label="Dimension Filter"
mergeChips
/>
diff --git a/packages/manager/src/features/CloudPulse/Alerts/Utils/utils.test.ts b/packages/manager/src/features/CloudPulse/Alerts/Utils/utils.test.ts
index d864249ba60..e2c4070cc43 100644
--- a/packages/manager/src/features/CloudPulse/Alerts/Utils/utils.test.ts
+++ b/packages/manager/src/features/CloudPulse/Alerts/Utils/utils.test.ts
@@ -15,7 +15,7 @@ it('test getServiceTypeLabel method', () => {
});
it('test convertSecondsToMinutes method', () => {
- expect(convertSecondsToMinutes(0)).toBe('0 minutes');
+ expect(convertSecondsToMinutes(0)).toBe('0 minute');
expect(convertSecondsToMinutes(60)).toBe('1 minute');
expect(convertSecondsToMinutes(120)).toBe('2 minutes');
expect(convertSecondsToMinutes(65)).toBe('1 minute and 5 seconds');
diff --git a/packages/manager/src/features/CloudPulse/Alerts/Utils/utils.ts b/packages/manager/src/features/CloudPulse/Alerts/Utils/utils.ts
index 201154aedbc..b9cbe3f7609 100644
--- a/packages/manager/src/features/CloudPulse/Alerts/Utils/utils.ts
+++ b/packages/manager/src/features/CloudPulse/Alerts/Utils/utils.ts
@@ -36,24 +36,41 @@ export const getAlertBoxStyles = (theme: Theme) => ({
* @returns A string representing the time in minutes and seconds.
*/
export const convertSecondsToMinutes = (seconds: number): string => {
- if (seconds === 0) {
- return '0 minutes';
+ if (seconds <= 0) {
+ return '0 minute';
}
-
const minutes = Math.floor(seconds / 60);
const remainingSeconds = seconds % 60;
+ const minuteString =
+ minutes > 0
+ ? `${minutes} ${minutes === 1 ? 'minute' : 'minutes'}`
+ : undefined;
+ const secondString =
+ remainingSeconds > 0
+ ? `${remainingSeconds} ${remainingSeconds <= 1 ? 'second' : 'seconds'}`
+ : undefined;
+ return [minuteString, secondString].filter(Boolean).join(' and ');
+};
- const minuteString = `${minutes} ${minutes === 1 ? 'minute' : 'minutes'}`;
- const secondString = `${remainingSeconds} ${
- remainingSeconds === 1 ? 'second' : 'seconds'
- }`;
-
- if (!minutes) {
- return secondString;
+/**
+ * @param index The index of the list of chips that we are rendering
+ * @param length The length of the iteration so far
+ * @returns The border radius to be applied on chips based on the parameters
+ */
+export const getAlertChipBorderRadius = (
+ index: number,
+ length: number,
+ mergeChips: boolean | undefined,
+ theme: Theme
+): string => {
+ if (!mergeChips || length === 1) {
+ return theme.spacing(0.3);
}
- if (!remainingSeconds) {
- return minuteString;
+ if (index === 0) {
+ return `${theme.spacing(0.3)} 0 0 ${theme.spacing(0.3)}`;
}
-
- return `${minuteString} and ${secondString}`;
+ if (index === length - 1) {
+ return `0 ${theme.spacing(0.3)} ${theme.spacing(0.3)} 0`;
+ }
+ return '0';
};
diff --git a/packages/manager/src/features/CloudPulse/Alerts/constants.ts b/packages/manager/src/features/CloudPulse/Alerts/constants.ts
index 87d1d521f3e..35c0fde6c6c 100644
--- a/packages/manager/src/features/CloudPulse/Alerts/constants.ts
+++ b/packages/manager/src/features/CloudPulse/Alerts/constants.ts
@@ -87,7 +87,7 @@ export const alertStatusToIconStatusMap: Record = {
enabled: 'active',
};
-export const operators: Record = {
+export const metricOperatorTypeMap: Record = {
eq: '=',
gt: '>',
gte: '>=',
@@ -95,7 +95,7 @@ export const operators: Record = {
lte: '<=',
};
-export const aggregationTypes: Record = {
+export const aggregationTypeMap: Record = {
avg: 'Average',
count: 'Count',
max: 'Maximum',
@@ -103,7 +103,10 @@ export const aggregationTypes: Record = {
sum: 'Sum',
};
-export const operatorLabel: Record = {
+export const dimensionOperatorTypeMap: Record<
+ DimensionFilterOperatorType,
+ string
+> = {
endswith: 'ends with',
eq: 'equals',
neq: 'not equals',