Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3660b289c3 | ||
|
|
a69da7cacf | ||
|
|
8d7a3cea9f |
@@ -1,8 +1,9 @@
|
||||
import { Select, Tooltip, Typography } from 'antd';
|
||||
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
||||
import { Info } from 'lucide-react';
|
||||
import { useMemo } from 'react';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
|
||||
import { ALL_SELECTED_VALUE } from '../constants';
|
||||
import { useCreateAlertState } from '../context';
|
||||
|
||||
function MultipleNotifications(): JSX.Element {
|
||||
@@ -12,6 +13,12 @@ function MultipleNotifications(): JSX.Element {
|
||||
} = useCreateAlertState();
|
||||
const { currentQuery } = useQueryBuilder();
|
||||
|
||||
const isAllOptionSelected = useMemo(
|
||||
() =>
|
||||
notificationSettings.multipleNotifications?.includes(ALL_SELECTED_VALUE),
|
||||
[notificationSettings.multipleNotifications],
|
||||
);
|
||||
|
||||
const spaceAggregationOptions = useMemo(() => {
|
||||
const allGroupBys = currentQuery.builder.queryData?.reduce<string[]>(
|
||||
(acc, query) => {
|
||||
@@ -21,15 +28,60 @@ function MultipleNotifications(): JSX.Element {
|
||||
[],
|
||||
);
|
||||
const uniqueGroupBys = [...new Set(allGroupBys)];
|
||||
return uniqueGroupBys.map((key) => ({
|
||||
const options = uniqueGroupBys.map((key) => ({
|
||||
label: key,
|
||||
value: key,
|
||||
disabled: isAllOptionSelected,
|
||||
'data-testid': 'multiple-notifications-select-option',
|
||||
}));
|
||||
}, [currentQuery.builder.queryData]);
|
||||
if (options.length > 0) {
|
||||
return [
|
||||
{
|
||||
label: 'All',
|
||||
value: ALL_SELECTED_VALUE,
|
||||
'data-testid': 'multiple-notifications-select-option',
|
||||
},
|
||||
...options,
|
||||
];
|
||||
}
|
||||
return options;
|
||||
}, [currentQuery.builder.queryData, isAllOptionSelected]);
|
||||
|
||||
const isMultipleNotificationsEnabled = spaceAggregationOptions.length > 0;
|
||||
|
||||
const onSelectChange = useCallback(
|
||||
(newSelectedOptions: string[]): void => {
|
||||
const currentSelectedOptions = notificationSettings.multipleNotifications;
|
||||
const allOptionLastSelected =
|
||||
!currentSelectedOptions?.includes(ALL_SELECTED_VALUE) &&
|
||||
newSelectedOptions.includes(ALL_SELECTED_VALUE);
|
||||
if (allOptionLastSelected) {
|
||||
setNotificationSettings({
|
||||
type: 'SET_MULTIPLE_NOTIFICATIONS',
|
||||
payload: [ALL_SELECTED_VALUE],
|
||||
});
|
||||
} else {
|
||||
setNotificationSettings({
|
||||
type: 'SET_MULTIPLE_NOTIFICATIONS',
|
||||
payload: newSelectedOptions,
|
||||
});
|
||||
}
|
||||
},
|
||||
[setNotificationSettings, notificationSettings.multipleNotifications],
|
||||
);
|
||||
|
||||
const groupByDescription = useMemo(() => {
|
||||
if (isAllOptionSelected) {
|
||||
return 'All = grouping of alerts is disabled';
|
||||
}
|
||||
if (notificationSettings.multipleNotifications?.length) {
|
||||
return `Alerts with same ${notificationSettings.multipleNotifications?.join(
|
||||
', ',
|
||||
)} will be grouped`;
|
||||
}
|
||||
return 'Empty = all matching alerts combined into one notification';
|
||||
}, [isAllOptionSelected, notificationSettings.multipleNotifications]);
|
||||
|
||||
const multipleNotificationsInput = useMemo(() => {
|
||||
const placeholder = isMultipleNotificationsEnabled
|
||||
? 'Select fields to group by (optional)'
|
||||
@@ -38,12 +90,7 @@ function MultipleNotifications(): JSX.Element {
|
||||
<div>
|
||||
<Select
|
||||
options={spaceAggregationOptions}
|
||||
onChange={(value): void => {
|
||||
setNotificationSettings({
|
||||
type: 'SET_MULTIPLE_NOTIFICATIONS',
|
||||
payload: value,
|
||||
});
|
||||
}}
|
||||
onChange={onSelectChange}
|
||||
value={notificationSettings.multipleNotifications}
|
||||
mode="multiple"
|
||||
placeholder={placeholder}
|
||||
@@ -54,11 +101,7 @@ function MultipleNotifications(): JSX.Element {
|
||||
/>
|
||||
{isMultipleNotificationsEnabled && (
|
||||
<Typography.Paragraph className="multiple-notifications-select-description">
|
||||
{notificationSettings.multipleNotifications?.length
|
||||
? `Alerts with same ${notificationSettings.multipleNotifications?.join(
|
||||
', ',
|
||||
)} will be grouped`
|
||||
: 'Empty = all matching alerts combined into one notification'}
|
||||
{groupByDescription}
|
||||
</Typography.Paragraph>
|
||||
)}
|
||||
</div>
|
||||
@@ -72,9 +115,10 @@ function MultipleNotifications(): JSX.Element {
|
||||
}
|
||||
return input;
|
||||
}, [
|
||||
groupByDescription,
|
||||
isMultipleNotificationsEnabled,
|
||||
notificationSettings.multipleNotifications,
|
||||
setNotificationSettings,
|
||||
onSelectChange,
|
||||
spaceAggregationOptions,
|
||||
]);
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { ALL_SELECTED_VALUE } from 'container/CreateAlertV2/constants';
|
||||
import * as createAlertContext from 'container/CreateAlertV2/context';
|
||||
import {
|
||||
INITIAL_ALERT_THRESHOLD_STATE,
|
||||
@@ -28,6 +29,9 @@ jest.mock('hooks/queryBuilder/useQueryBuilder', () => ({
|
||||
}));
|
||||
|
||||
const TEST_QUERY = 'test-query';
|
||||
const TEST_QUERY_2 = 'test-query-2';
|
||||
const ANT_SELECT_ITEM_OPTION_CONTENT_SELECTOR =
|
||||
'.ant-select-item-option-content';
|
||||
const TEST_GROUP_BY_FIELDS = [{ key: 'service' }, { key: 'environment' }];
|
||||
const TRUE = 'true';
|
||||
const FALSE = 'false';
|
||||
@@ -151,7 +155,7 @@ describe('MultipleNotifications', () => {
|
||||
groupBy: [{ key: 'http.status_code' }],
|
||||
},
|
||||
{
|
||||
queryName: 'test-query-2',
|
||||
queryName: TEST_QUERY_2,
|
||||
groupBy: [{ key: 'service' }],
|
||||
},
|
||||
],
|
||||
@@ -165,8 +169,121 @@ describe('MultipleNotifications', () => {
|
||||
await userEvent.click(select);
|
||||
|
||||
expect(
|
||||
screen.getByRole('option', { name: 'http.status_code' }),
|
||||
screen.getByText('http.status_code', {
|
||||
selector: ANT_SELECT_ITEM_OPTION_CONTENT_SELECTOR,
|
||||
}),
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByRole('option', { name: 'service' })).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText('service', {
|
||||
selector: ANT_SELECT_ITEM_OPTION_CONTENT_SELECTOR,
|
||||
}),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText('All', {
|
||||
selector: ANT_SELECT_ITEM_OPTION_CONTENT_SELECTOR,
|
||||
}),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('selecting the "all" option shows correct group by description', () => {
|
||||
useQueryBuilder.mockReturnValue({
|
||||
currentQuery: {
|
||||
builder: {
|
||||
queryData: [
|
||||
{
|
||||
queryName: TEST_QUERY_2,
|
||||
groupBy: [{ key: 'service' }],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
});
|
||||
jest.spyOn(createAlertContext, 'useCreateAlertState').mockReturnValue(
|
||||
createMockAlertContextState({
|
||||
notificationSettings: {
|
||||
...INITIAL_NOTIFICATION_SETTINGS_STATE,
|
||||
multipleNotifications: [ALL_SELECTED_VALUE],
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
render(<MultipleNotifications />);
|
||||
|
||||
expect(
|
||||
screen.getByText('All = grouping of alerts is disabled'),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('selecting "all" option should disable selection of other options', async () => {
|
||||
useQueryBuilder.mockReturnValue({
|
||||
currentQuery: {
|
||||
builder: {
|
||||
queryData: [
|
||||
{
|
||||
queryName: TEST_QUERY_2,
|
||||
groupBy: [{ key: 'service' }],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
});
|
||||
jest.spyOn(createAlertContext, 'useCreateAlertState').mockReturnValue(
|
||||
createMockAlertContextState({
|
||||
notificationSettings: {
|
||||
...INITIAL_NOTIFICATION_SETTINGS_STATE,
|
||||
multipleNotifications: [ALL_SELECTED_VALUE],
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
render(<MultipleNotifications />);
|
||||
|
||||
const select = screen.getByRole(COMBOBOX_ROLE);
|
||||
await userEvent.click(select);
|
||||
|
||||
const serviceOption = screen.getAllByTestId(
|
||||
'multiple-notifications-select-option',
|
||||
);
|
||||
expect(serviceOption).toHaveLength(2);
|
||||
expect(serviceOption[0]).not.toHaveClass('ant-select-item-option-disabled');
|
||||
expect(serviceOption[1]).toHaveClass('ant-select-item-option-disabled');
|
||||
});
|
||||
|
||||
it('selecting all option should remove all other selected options', async () => {
|
||||
useQueryBuilder.mockReturnValue({
|
||||
currentQuery: {
|
||||
builder: {
|
||||
queryData: [
|
||||
{
|
||||
queryName: TEST_QUERY_2,
|
||||
groupBy: [{ key: 'service' }],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
});
|
||||
jest.spyOn(createAlertContext, 'useCreateAlertState').mockReturnValue(
|
||||
createMockAlertContextState({
|
||||
notificationSettings: {
|
||||
...INITIAL_NOTIFICATION_SETTINGS_STATE,
|
||||
multipleNotifications: ['service', 'environment'],
|
||||
},
|
||||
setNotificationSettings: mockSetNotificationSettings,
|
||||
}),
|
||||
);
|
||||
|
||||
render(<MultipleNotifications />);
|
||||
const select = screen.getByRole(COMBOBOX_ROLE);
|
||||
await userEvent.click(select);
|
||||
|
||||
const serviceOption = screen.getAllByTestId(
|
||||
'multiple-notifications-select-option',
|
||||
);
|
||||
expect(serviceOption).toHaveLength(2);
|
||||
await userEvent.click(serviceOption[0]);
|
||||
expect(mockSetNotificationSettings).toHaveBeenCalledWith({
|
||||
type: 'SET_MULTIPLE_NOTIFICATIONS',
|
||||
payload: [ALL_SELECTED_VALUE],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -72,3 +72,5 @@ export const defaultPostableAlertRuleV2: PostableAlertRuleV2 = {
|
||||
alert: 'TEST_ALERT',
|
||||
evaluation: defaultEvaluation,
|
||||
};
|
||||
|
||||
export const ALL_SELECTED_VALUE = '__all__';
|
||||
|
||||
Reference in New Issue
Block a user