Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
b3c2b75
upcoming: [DI-24451] - Added confirmation dialog on enabling/disablin…
nikhagra-akamai Apr 3, 2025
b5c005c
test: [DI-24451] - Fixed cypress tests
nikhagra-akamai Apr 4, 2025
0c07726
upcoming: [DI-24451] - Updated message
nikhagra-akamai Apr 4, 2025
654e19e
upcoming: [DI-24451] - Variable renaming
nikhagra-akamai Apr 4, 2025
f19ccdc
upcoming: [DI-24451] - added code documentation
nikhagra-akamai Apr 4, 2025
f7d4c71
Changed typography variant of confirmation dialog message
nikhagra-akamai Apr 7, 2025
8e5c227
upcoming: [DI-24451] - Updated dialog message
nikhagra-akamai Apr 7, 2025
dd1e664
upcoming: [DI-24451] - Updated failing cypress test
nikhagra-akamai Apr 8, 2025
1272ca3
upcoming: [DI-24451] - Remove unused callback
nikhagra-akamai Apr 8, 2025
6ba7b1c
test: [DI-24452]-Cypress automation for User alerts - enable/disable …
agorthi-akamai Apr 7, 2025
fc70e1b
test: [DI-24451] - Updated test cases
nikhagra-akamai Apr 8, 2025
7163abc
upcoming: [DI-24451] - Removed title from from alert confirmation dialog
nikhagra-akamai Apr 8, 2025
5e89971
test: [DI-24451] - Updated cypress test
nikhagra-akamai Apr 8, 2025
11a0f34
typecheck fix
nikhagra-akamai Apr 8, 2025
95d30c6
added changeset
nikhagra-akamai Apr 8, 2025
039f42d
test: [DI-24451] - Updated interface
nikhagra-akamai Apr 8, 2025
3689a77
Merge branch 'develop' of github.com:linode/manager into alert/confir…
nikhagra-akamai Apr 8, 2025
fe39e2d
test: [DI-24451] - Updated test case
nikhagra-akamai Apr 8, 2025
e543bac
Merge branch 'develop' into alert/confirm_dialog
nikhagra-akamai Apr 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Upcoming Features
---

Add `Confirmation Dialog` in `AlertListTable.tsx`, add `message` prop in `AlertConfirmationDialog.tsx` ([#11981](https://github.com/linode/manager/pull/11981))
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ describe('Alerts Listing Page - Error Handling', () => {
});

ui.actionMenuItem.findByTitle(action).should('be.visible').click();
ui.button.findByTitle(action).should('be.visible').click();
cy.wait(alias).then(({ response }) => {
ui.toast.assertMessage(response?.body.errors[0].reason);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,17 @@ const mockAlerts = [
}),
];

interface AlertActionOptions {
action: 'Disable' | 'Enable';
alertName: string;
alias: string;
}

interface AlertToggleOptions extends AlertActionOptions {
confirmationText: string;
successMessage: string;
}

/**
* @description
* This code validates the presence and correct text of the table headers
Expand Down Expand Up @@ -305,12 +316,13 @@ describe('Integration Tests for CloudPulse Alerts Listing Page', () => {
};

// Function to toggle an alert's status
const toggleAlertStatus = (
alertName: string,
action: 'Disable' | 'Enable',
alias: string,
successMessage: string
) => {
const toggleAlertStatus = ({
action,
alertName,
alias,
confirmationText,
successMessage,
}: AlertToggleOptions) => {
cy.findByText(alertName)
.should('be.visible')
.closest('tr')
Expand All @@ -320,29 +332,48 @@ describe('Integration Tests for CloudPulse Alerts Listing Page', () => {
.should('be.visible')
.click();
});

ui.actionMenuItem.findByTitle(action).should('be.visible').click();

cy.wait(alias).then(({ response }) => {
// verify dialog title
ui.dialog
.findByTitle(`${action} ${alertName} Alert?`)
.should('be.visible')
.within(() => {
cy.findByText(confirmationText).should('be.visible');
ui.button
.findByTitle(action)
.should('be.visible')
.should('be.enabled')
.click();
});

cy.wait(alias).then(({}) => {
ui.toast.assertMessage(successMessage);
});
};
// Disable "Alert-1"
searchAlert('Alert-1');
toggleAlertStatus(
'Alert-1',
'Disable',
'@getFirstAlertDefinitions',
UPDATE_ALERT_SUCCESS_MESSAGE
);
const actions: Array<AlertActionOptions> = [
{
action: 'Disable',
alertName: 'Alert-1',
alias: '@getFirstAlertDefinitions',
},
{
action: 'Enable',
alertName: 'Alert-2',
alias: '@getSecondAlertDefinitions',
},
];

// Enable "Alert-2"
searchAlert('Alert-2');
toggleAlertStatus(
'Alert-2',
'Enable',
'@getSecondAlertDefinitions',
UPDATE_ALERT_SUCCESS_MESSAGE
);
actions.forEach(({ action, alertName, alias }) => {
searchAlert(alertName);
toggleAlertStatus({
action,
alertName,
alias,
confirmationText: `Are you sure you want to ${action.toLowerCase()} this alert definition?`,
successMessage: UPDATE_ALERT_SUCCESS_MESSAGE,
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -9,35 +9,39 @@ import { AlertConfirmationDialog } from './AlertConfirmationDialog';
const entityName = 'entity-1';
const alert = alertFactory.build({ service_type: 'dbaas' });
const confirmFunction = vi.fn();
const messages = {
disableMessage: `Are you sure you want to disable the alert for ${entityName}?`,
disableTitle: `Disable ${alert.label} Alert?`,
enableMessage: `Are you sure you want to enable the alert for ${entityName}?`,
enableTitle: `Enable ${alert.label} Alert?`,
};

describe('Alert confirmation dialog', () => {
it('should show confirmation dialog', () => {
const { getByTestId, getByText } = renderWithTheme(
<AlertConfirmationDialog
alert={alert}
entityName={entityName}
handleCancel={vi.fn()}
handleConfirm={confirmFunction}
isActive={true}
isEnabled={true}
isOpen={true}
message={messages.disableMessage}
/>
);

expect(getByTestId('confirmation-dialog')).toBeInTheDocument();
expect(getByText(`Disable ${alert.label} Alert?`)).toBeVisible();
expect(
getByText(`Are you sure you want to disable the alert for ${entityName}?`)
).toBeInTheDocument();
expect(getByText(messages.disableTitle)).toBeVisible();
expect(getByText(messages.disableMessage)).toBeInTheDocument();
});
it('should click confirm button', async () => {
const { getByText } = renderWithTheme(
<AlertConfirmationDialog
alert={alert}
entityName={entityName}
handleCancel={vi.fn()}
handleConfirm={confirmFunction}
isActive={true}
isEnabled={true}
isOpen={true}
message={messages.disableMessage}
/>
);

Expand All @@ -51,18 +55,16 @@ describe('Alert confirmation dialog', () => {
const { getByTestId, getByText } = renderWithTheme(
<AlertConfirmationDialog
alert={alert}
entityName={entityName}
handleCancel={vi.fn()}
handleConfirm={confirmFunction}
isActive={false}
isEnabled={false}
isOpen={true}
message={messages.enableMessage}
/>
);

expect(getByTestId('confirmation-dialog')).toBeInTheDocument();
expect(getByText(`Enable ${alert.label} Alert?`)).toBeVisible();
expect(
getByText(`Are you sure you want to enable the alert for ${entityName}?`)
).toBeInTheDocument();
expect(getByText(messages.enableTitle)).toBeVisible();
expect(getByText(messages.enableMessage)).toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,6 @@ interface AlertConfirmationDialogProps {
*/
alert: Alert;

/**
* Name of the selected entity
*/
entityName: string;

/**
* Handler function for cancel button
*/
Expand All @@ -31,7 +26,7 @@ interface AlertConfirmationDialogProps {
/**
* Current state of the toggle button whether active or not
*/
isActive: boolean;
isEnabled: boolean;

/**
* Loading state of the confirmation dialog
Expand All @@ -42,26 +37,31 @@ interface AlertConfirmationDialogProps {
* Current state of the confirmation dialoge whether open or not
*/
isOpen: boolean;

/**
* Message to be displayed in the confirmation dialog
*/
message: string;
}

export const AlertConfirmationDialog = React.memo(
(props: AlertConfirmationDialogProps) => {
const {
alert,
entityName,
handleCancel,
handleConfirm,
isActive,
isEnabled,
isLoading = false,
isOpen,
message,
} = props;

const actionsPanel = (
<ActionsPanel
primaryButtonProps={{
label: isActive ? 'Disable' : 'Enable',
label: isEnabled ? 'Disable' : 'Enable',
loading: isLoading,
onClick: () => handleConfirm(alert, isActive),
onClick: () => handleConfirm(alert, isEnabled),
}}
secondaryButtonProps={{
disabled: isLoading,
Expand All @@ -77,12 +77,9 @@ export const AlertConfirmationDialog = React.memo(
data-testid="confirmation-dialog"
onClose={handleCancel}
open={isOpen}
title={`${isActive ? 'Disable' : 'Enable'} ${alert.label} Alert?`}
title={`${isEnabled ? 'Disable' : 'Enable'} ${alert.label} Alert?`}
>
<Typography variant="subtitle1">
Are you sure you want to {isActive ? 'disable' : 'enable'} the alert
for {entityName}?
</Typography>
<Typography variant="subtitle2">{message}</Typography>
</ConfirmationDialog>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,12 @@ describe('Alert List Table test', () => {

it('should show success snackbar when enabling alert succeeds', async () => {
const alert = alertFactory.build({ status: 'disabled', type: 'user' });
const { getByLabelText, getByText } = renderWithTheme(
const {
getByLabelText,
getByRole,
getByTestId,
getByText,
} = renderWithTheme(
<AlertsListTable
alerts={[alert]}
isLoading={false}
Expand All @@ -98,12 +103,22 @@ describe('Alert List Table test', () => {
const actionMenu = getByLabelText(`Action menu for Alert ${alert.label}`);
await userEvent.click(actionMenu);
await userEvent.click(getByText('Enable')); // click the enable button to enable alert

expect(getByTestId('confirmation-dialog')).toBeInTheDocument();

await userEvent.click(getByRole('button', { name: 'Enable' }));

expect(getByText(UPDATE_ALERT_SUCCESS_MESSAGE)).toBeInTheDocument(); // validate whether snackbar is displayed properly
});

it('should show success snackbar when disabling alert succeeds', async () => {
const alert = alertFactory.build({ status: 'enabled', type: 'user' });
const { getByLabelText, getByText } = renderWithTheme(
const {
getByLabelText,
getByRole,
getByTestId,
getByText,
} = renderWithTheme(
<AlertsListTable
alerts={[alert]}
isLoading={false}
Expand All @@ -115,6 +130,11 @@ describe('Alert List Table test', () => {
const actionMenu = getByLabelText(`Action menu for Alert ${alert.label}`);
await userEvent.click(actionMenu);
await userEvent.click(getByText('Disable')); // click the enable button to enable alert

expect(getByTestId('confirmation-dialog')).toBeInTheDocument();

await userEvent.click(getByRole('button', { name: 'Disable' }));

expect(getByText(UPDATE_ALERT_SUCCESS_MESSAGE)).toBeInTheDocument(); // validate whether snackbar is displayed properly
});

Expand All @@ -126,7 +146,12 @@ describe('Alert List Table test', () => {
});

const alert = alertFactory.build({ status: 'disabled', type: 'user' });
const { getByLabelText, getByText } = renderWithTheme(
const {
getByLabelText,
getByRole,
getByTestId,
getByText,
} = renderWithTheme(
<AlertsListTable
alerts={[alert]}
isLoading={false}
Expand All @@ -139,6 +164,10 @@ describe('Alert List Table test', () => {
await userEvent.click(actionMenu);
await userEvent.click(getByText('Enable'));

expect(getByTestId('confirmation-dialog')).toBeInTheDocument();

await userEvent.click(getByRole('button', { name: 'Enable' }));

expect(getByText('Enabling alert failed')).toBeInTheDocument(); // validate whether snackbar is displayed properly if an error is encountered while enabling an alert
});

Expand All @@ -150,7 +179,12 @@ describe('Alert List Table test', () => {
});

const alert = alertFactory.build({ status: 'enabled', type: 'user' });
const { getByLabelText, getByText } = renderWithTheme(
const {
getByLabelText,
getByRole,
getByTestId,
getByText,
} = renderWithTheme(
<AlertsListTable
alerts={[alert]}
isLoading={false}
Expand All @@ -163,6 +197,10 @@ describe('Alert List Table test', () => {
await userEvent.click(actionMenu);
await userEvent.click(getByText('Disable'));

expect(getByTestId('confirmation-dialog')).toBeInTheDocument();

await userEvent.click(getByRole('button', { name: 'Disable' }));

expect(getByText('Disabling alert failed')).toBeInTheDocument(); // validate whether snackbar is displayed properly if an error is encountered while disabling an alert
});
});
Loading