From b3c2b75109d8901114d54f14086cadaadd7bc39e Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Thu, 3 Apr 2025 19:43:34 +0530 Subject: [PATCH 01/17] upcoming: [DI-24451] - Added confirmation dialog on enabling/disabling of alert --- .../AlertConfirmationDialog.test.tsx | 15 +- .../AlertsLanding/AlertConfirmationDialog.tsx | 19 +- .../AlertsListing/AlertListTable.test.tsx | 46 +++- .../Alerts/AlertsListing/AlertListTable.tsx | 236 +++++++++++------- .../AlertInformationActionTable.tsx | 17 +- 5 files changed, 216 insertions(+), 117 deletions(-) diff --git a/packages/manager/src/features/CloudPulse/Alerts/AlertsLanding/AlertConfirmationDialog.test.tsx b/packages/manager/src/features/CloudPulse/Alerts/AlertsLanding/AlertConfirmationDialog.test.tsx index a6c52bbd471..22c1ee421e5 100644 --- a/packages/manager/src/features/CloudPulse/Alerts/AlertsLanding/AlertConfirmationDialog.test.tsx +++ b/packages/manager/src/features/CloudPulse/Alerts/AlertsLanding/AlertConfirmationDialog.test.tsx @@ -11,15 +11,18 @@ const alert = alertFactory.build({ service_type: 'dbaas' }); const confirmFunction = vi.fn(); describe('Alert confirmation dialog', () => { + const message = `Are you sure you want to disable the alert for ${entityName}?`; + const title = `Disable ${alert.label} Alert?`; it('should show confirmation dialog', () => { const { getByTestId, getByText } = renderWithTheme( ); @@ -30,14 +33,17 @@ describe('Alert confirmation dialog', () => { ).toBeInTheDocument(); }); it('should click confirm button', async () => { + const message = `Are you sure you want to disable the alert for ${entityName}?`; + const title = `Disable ${alert.label} Alert?`; const { getByText } = renderWithTheme( ); @@ -48,14 +54,17 @@ describe('Alert confirmation dialog', () => { expect(confirmFunction).toBeCalledWith(alert, true); }); it('should show enable text', async () => { + const message = `Are you sure you want to enable the alert for ${entityName}?`; + const title = `Enable ${alert.label} Alert?`; const { getByTestId, getByText } = renderWithTheme( ); diff --git a/packages/manager/src/features/CloudPulse/Alerts/AlertsLanding/AlertConfirmationDialog.tsx b/packages/manager/src/features/CloudPulse/Alerts/AlertsLanding/AlertConfirmationDialog.tsx index 9afecdfce86..56cbf460e9b 100644 --- a/packages/manager/src/features/CloudPulse/Alerts/AlertsLanding/AlertConfirmationDialog.tsx +++ b/packages/manager/src/features/CloudPulse/Alerts/AlertsLanding/AlertConfirmationDialog.tsx @@ -11,11 +11,6 @@ interface AlertConfirmationDialogProps { */ alert: Alert; - /** - * Name of the selected entity - */ - entityName: string; - /** * Handler function for cancel button */ @@ -42,18 +37,23 @@ interface AlertConfirmationDialogProps { * Current state of the confirmation dialoge whether open or not */ isOpen: boolean; + + message: string; + + title: string; } export const AlertConfirmationDialog = React.memo( (props: AlertConfirmationDialogProps) => { const { alert, - entityName, handleCancel, handleConfirm, isActive, isLoading = false, isOpen, + message, + title, } = props; const actionsPanel = ( @@ -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={title} > - - Are you sure you want to {isActive ? 'disable' : 'enable'} the alert - for {entityName}? - + {message} ); } diff --git a/packages/manager/src/features/CloudPulse/Alerts/AlertsListing/AlertListTable.test.tsx b/packages/manager/src/features/CloudPulse/Alerts/AlertsListing/AlertListTable.test.tsx index 8ebd5c96310..e8f30ca8953 100644 --- a/packages/manager/src/features/CloudPulse/Alerts/AlertsListing/AlertListTable.test.tsx +++ b/packages/manager/src/features/CloudPulse/Alerts/AlertsListing/AlertListTable.test.tsx @@ -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( { 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( { 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 }); @@ -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( { 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 }); @@ -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( { 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 }); }); diff --git a/packages/manager/src/features/CloudPulse/Alerts/AlertsListing/AlertListTable.tsx b/packages/manager/src/features/CloudPulse/Alerts/AlertsListing/AlertListTable.tsx index 4523734aa4f..8dbd3ddd746 100644 --- a/packages/manager/src/features/CloudPulse/Alerts/AlertsListing/AlertListTable.tsx +++ b/packages/manager/src/features/CloudPulse/Alerts/AlertsListing/AlertListTable.tsx @@ -14,6 +14,7 @@ import { TableSortCell } from 'src/components/TableSortCell'; import { useEditAlertDefinition } from 'src/queries/cloudpulse/alerts'; import { getAPIErrorOrDefault } from 'src/utilities/errorUtils'; +import { AlertConfirmationDialog } from '../AlertsLanding/AlertConfirmationDialog'; import { UPDATE_ALERT_SUCCESS_MESSAGE } from '../constants'; import { AlertTableRow } from './AlertTableRow'; import { AlertListingTableLabelMap } from './constants'; @@ -52,6 +53,10 @@ export const AlertsListTable = React.memo((props: AlertsListTableProps) => { const history = useHistory(); const { mutateAsync: editAlertDefinition } = useEditAlertDefinition(); // put call to update alert status + const [selectedAlert, setSelectedAlert] = React.useState({} as Alert); + const [isDialogOpen, setIsDialogOpen] = React.useState(false); + const [isUpdating, setIsUpdating] = React.useState(false); + const handleDetails = ({ id: _id, service_type: serviceType }: Alert) => { history.push(`${location.pathname}/detail/${serviceType}/${_id}`); }; @@ -60,11 +65,20 @@ export const AlertsListTable = React.memo((props: AlertsListTableProps) => { history.push(`${location.pathname}/edit/${serviceType}/${id}`); }; - const handleEnableDisable = React.useCallback( - (alert: Alert) => { - const toggleStatus = alert.status === 'enabled' ? 'disabled' : 'enabled'; - const errorStatus = - toggleStatus === 'disabled' ? 'Disabling' : 'Enabling'; + const handleEnableDisable = React.useCallback((alert: Alert) => { + setSelectedAlert(alert); + setIsDialogOpen(true); + }, []); + + const handleCancel = React.useCallback(() => { + setIsDialogOpen(false); + }, []); + + const handleConfirm = React.useCallback( + (alert: Alert, currentStatus: boolean) => { + const toggleStatus = currentStatus ? 'disabled' : 'enabled'; + const errorStatus = currentStatus ? 'Disabling' : 'Enabling'; + setIsUpdating(true); editAlertDefinition({ alertId: alert.id, serviceType: alert.service_type, @@ -85,105 +99,133 @@ export const AlertsListTable = React.memo((props: AlertsListTableProps) => { enqueueSnackbar(errorResponse[0].reason, { variant: 'error', }); + }) + .finally(() => { + setIsDialogOpen(false); + setIsUpdating(false); }); }, [editAlertDefinition] ); + let isActive = false; + + let message = ''; + let title = ''; + if (isDialogOpen) { + isActive = selectedAlert.status !== 'disabled'; + message = + 'Are you sure you want to disable this alert for all assigned resources'; + title = `${isActive ? 'Disable' : 'Enable'} ${selectedAlert.label} Alert?`; + } + return ( - - {({ data: orderedData, handleOrderChange, order, orderBy }) => ( - - {({ - count, - data: paginatedAndOrderedAlerts, - handlePageChange, - handlePageSizeChange, - page, - pageSize, - }) => ( - <> - - - - - {AlertListingTableLabelMap.map((value) => ( - { - if (order) { - handleOrderChange(orderBy, order); - handlePageChange(1); - } + <> + + {({ data: orderedData, handleOrderChange, order, orderBy }) => ( + + {({ + count, + data: paginatedAndOrderedAlerts, + handlePageChange, + handlePageSizeChange, + page, + pageSize, + }) => ( + <> + +
+ + + {AlertListingTableLabelMap.map((value) => ( + { + if (order) { + handleOrderChange(orderBy, order); + handlePageChange(1); + } + }} + active={orderBy === value.label} + data-qa-header={value.label} + data-qa-sorting={value.label} + direction={order} + key={value.label} + label={value.label} + noWrap + > + {value.colName} + + ))} + + + + + + {paginatedAndOrderedAlerts?.map((alert) => ( + handleDetails(alert), + handleEdit: () => handleEdit(alert), + handleEnableDisable: () => + handleEnableDisable(alert), }} - active={orderBy === value.label} - data-qa-header={value.label} - data-qa-sorting={value.label} - direction={order} - key={value.label} - label={value.label} - noWrap - > - {value.colName} - + alert={alert} + key={alert.id} + services={services} + /> ))} - - - - - - {paginatedAndOrderedAlerts?.map((alert) => ( - handleDetails(alert), - handleEdit: () => handleEdit(alert), - handleEnableDisable: () => handleEnableDisable(alert), - }} - alert={alert} - key={alert.id} - services={services} - /> - ))} - -
-
- { - handlePageChange(page); - requestAnimationFrame(() => { - scrollToElement(); - }); - }} - handleSizeChange={(pageSize) => { - handlePageSizeChange(pageSize); - handlePageChange(1); - requestAnimationFrame(() => { - scrollToElement(); - }); - }} - count={count} - eventCategory="Alert Definitions Table" - page={page} - pageSize={pageSize} - sx={{ border: 0 }} - /> - - )} -
- )} -
+ + + + { + handlePageChange(page); + requestAnimationFrame(() => { + scrollToElement(); + }); + }} + handleSizeChange={(pageSize) => { + handlePageSizeChange(pageSize); + handlePageChange(1); + requestAnimationFrame(() => { + scrollToElement(); + }); + }} + count={count} + eventCategory="Alert Definitions Table" + page={page} + pageSize={pageSize} + sx={{ border: 0 }} + /> + + )} + + )} + + + ); }); diff --git a/packages/manager/src/features/CloudPulse/Alerts/ContextualView/AlertInformationActionTable.tsx b/packages/manager/src/features/CloudPulse/Alerts/ContextualView/AlertInformationActionTable.tsx index fdc98763b18..d3489939859 100644 --- a/packages/manager/src/features/CloudPulse/Alerts/ContextualView/AlertInformationActionTable.tsx +++ b/packages/manager/src/features/CloudPulse/Alerts/ContextualView/AlertInformationActionTable.tsx @@ -120,6 +120,18 @@ export const AlertInformationActionTable = ( setIsDialogOpen(true); setSelectedAlert(alert); }; + + let isActive = false; + + let message = ''; + let title = ''; + if (isDialogOpen) { + isActive = selectedAlert.entity_ids?.includes(entityId) ?? false; + message = `Are you sure you want to + ${isActive ? 'disable' : 'enable'} the alert for ${entityName}?`; + title = `${isActive ? 'Disable' : 'Enable'} ${selectedAlert.label} Alert?`; + } + return ( <> @@ -192,12 +204,13 @@ export const AlertInformationActionTable = ( ); From b5c005cd3ec17cc0680018ba9d6de3b7a5c3f5f1 Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Fri, 4 Apr 2025 11:23:59 +0530 Subject: [PATCH 02/17] test: [DI-24451] - Fixed cypress tests --- .../manager/cypress/e2e/core/cloudpulse/alert-errors.spec.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/manager/cypress/e2e/core/cloudpulse/alert-errors.spec.ts b/packages/manager/cypress/e2e/core/cloudpulse/alert-errors.spec.ts index 0163f19851c..328620c8cf5 100644 --- a/packages/manager/cypress/e2e/core/cloudpulse/alert-errors.spec.ts +++ b/packages/manager/cypress/e2e/core/cloudpulse/alert-errors.spec.ts @@ -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); }); From 0c077262bc9154bfeb2b39f1c9c60be155ea53ee Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Fri, 4 Apr 2025 11:38:21 +0530 Subject: [PATCH 03/17] upcoming: [DI-24451] - Updated message --- .../CloudPulse/Alerts/AlertsListing/AlertListTable.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/manager/src/features/CloudPulse/Alerts/AlertsListing/AlertListTable.tsx b/packages/manager/src/features/CloudPulse/Alerts/AlertsListing/AlertListTable.tsx index 8dbd3ddd746..bdbcd3c96f2 100644 --- a/packages/manager/src/features/CloudPulse/Alerts/AlertsListing/AlertListTable.tsx +++ b/packages/manager/src/features/CloudPulse/Alerts/AlertsListing/AlertListTable.tsx @@ -114,8 +114,10 @@ export const AlertsListTable = React.memo((props: AlertsListTableProps) => { let title = ''; if (isDialogOpen) { isActive = selectedAlert.status !== 'disabled'; - message = - 'Are you sure you want to disable this alert for all assigned resources'; + message = `Are you sure you want to ${ + isActive ? 'disable' : 'enable' + } this alert for all assigned resources?`; + title = `${isActive ? 'Disable' : 'Enable'} ${selectedAlert.label} Alert?`; } From 654e19e2c9d2eda8c527777f3ebf30fa3cedc82f Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Fri, 4 Apr 2025 12:40:07 +0530 Subject: [PATCH 04/17] upcoming: [DI-24451] - Variable renaming --- .../ContextualView/AlertInformationActionTable.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/manager/src/features/CloudPulse/Alerts/ContextualView/AlertInformationActionTable.tsx b/packages/manager/src/features/CloudPulse/Alerts/ContextualView/AlertInformationActionTable.tsx index d3489939859..a6b293d7e79 100644 --- a/packages/manager/src/features/CloudPulse/Alerts/ContextualView/AlertInformationActionTable.tsx +++ b/packages/manager/src/features/CloudPulse/Alerts/ContextualView/AlertInformationActionTable.tsx @@ -121,15 +121,15 @@ export const AlertInformationActionTable = ( setSelectedAlert(alert); }; - let isActive = false; + let isEnabled = false; let message = ''; let title = ''; if (isDialogOpen) { - isActive = selectedAlert.entity_ids?.includes(entityId) ?? false; + isEnabled = selectedAlert.entity_ids?.includes(entityId) ?? false; message = `Are you sure you want to - ${isActive ? 'disable' : 'enable'} the alert for ${entityName}?`; - title = `${isActive ? 'Disable' : 'Enable'} ${selectedAlert.label} Alert?`; + ${isEnabled ? 'disable' : 'enable'} the alert for ${entityName}?`; + title = `${isEnabled ? 'Disable' : 'Enable'} ${selectedAlert.label} Alert?`; } return ( @@ -206,7 +206,7 @@ export const AlertInformationActionTable = ( alert={selectedAlert} handleCancel={handleCancel} handleConfirm={handleConfirm} - isActive={isActive} + isEnabled={isEnabled} isLoading={isLoading} isOpen={isDialogOpen} message={message} From f19ccdc9ed20b376e71a8e4fa355306f9fa5d67b Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Fri, 4 Apr 2025 12:49:32 +0530 Subject: [PATCH 05/17] upcoming: [DI-24451] - added code documentation --- .../AlertsLanding/AlertConfirmationDialog.test.tsx | 6 +++--- .../AlertsLanding/AlertConfirmationDialog.tsx | 14 ++++++++++---- .../Alerts/AlertsListing/AlertListTable.tsx | 10 +++++----- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/packages/manager/src/features/CloudPulse/Alerts/AlertsLanding/AlertConfirmationDialog.test.tsx b/packages/manager/src/features/CloudPulse/Alerts/AlertsLanding/AlertConfirmationDialog.test.tsx index 22c1ee421e5..2072e284d59 100644 --- a/packages/manager/src/features/CloudPulse/Alerts/AlertsLanding/AlertConfirmationDialog.test.tsx +++ b/packages/manager/src/features/CloudPulse/Alerts/AlertsLanding/AlertConfirmationDialog.test.tsx @@ -19,7 +19,7 @@ describe('Alert confirmation dialog', () => { alert={alert} handleCancel={vi.fn()} handleConfirm={confirmFunction} - isActive={true} + isEnabled={true} isOpen={true} message={message} title={title} @@ -40,7 +40,7 @@ describe('Alert confirmation dialog', () => { alert={alert} handleCancel={vi.fn()} handleConfirm={confirmFunction} - isActive={true} + isEnabled={true} isOpen={true} message={message} title={title} @@ -61,7 +61,7 @@ describe('Alert confirmation dialog', () => { alert={alert} handleCancel={vi.fn()} handleConfirm={confirmFunction} - isActive={false} + isEnabled={false} isOpen={true} message={message} title={title} diff --git a/packages/manager/src/features/CloudPulse/Alerts/AlertsLanding/AlertConfirmationDialog.tsx b/packages/manager/src/features/CloudPulse/Alerts/AlertsLanding/AlertConfirmationDialog.tsx index 56cbf460e9b..01f89164688 100644 --- a/packages/manager/src/features/CloudPulse/Alerts/AlertsLanding/AlertConfirmationDialog.tsx +++ b/packages/manager/src/features/CloudPulse/Alerts/AlertsLanding/AlertConfirmationDialog.tsx @@ -26,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 @@ -38,8 +38,14 @@ interface AlertConfirmationDialogProps { */ isOpen: boolean; + /** + * Message to be displayed in the confirmation dialog + */ message: string; + /** + * Title of the confirmation dialog + */ title: string; } @@ -49,7 +55,7 @@ export const AlertConfirmationDialog = React.memo( alert, handleCancel, handleConfirm, - isActive, + isEnabled, isLoading = false, isOpen, message, @@ -59,9 +65,9 @@ export const AlertConfirmationDialog = React.memo( const actionsPanel = ( handleConfirm(alert, isActive), + onClick: () => handleConfirm(alert, isEnabled), }} secondaryButtonProps={{ disabled: isLoading, diff --git a/packages/manager/src/features/CloudPulse/Alerts/AlertsListing/AlertListTable.tsx b/packages/manager/src/features/CloudPulse/Alerts/AlertsListing/AlertListTable.tsx index bdbcd3c96f2..e7de2091467 100644 --- a/packages/manager/src/features/CloudPulse/Alerts/AlertsListing/AlertListTable.tsx +++ b/packages/manager/src/features/CloudPulse/Alerts/AlertsListing/AlertListTable.tsx @@ -108,17 +108,17 @@ export const AlertsListTable = React.memo((props: AlertsListTableProps) => { [editAlertDefinition] ); - let isActive = false; + let isEnabled = false; let message = ''; let title = ''; if (isDialogOpen) { - isActive = selectedAlert.status !== 'disabled'; + isEnabled = selectedAlert.status !== 'disabled'; message = `Are you sure you want to ${ - isActive ? 'disable' : 'enable' + isEnabled ? 'disable' : 'enable' } this alert for all assigned resources?`; - title = `${isActive ? 'Disable' : 'Enable'} ${selectedAlert.label} Alert?`; + title = `${isEnabled ? 'Disable' : 'Enable'} ${selectedAlert.label} Alert?`; } return ( @@ -222,7 +222,7 @@ export const AlertsListTable = React.memo((props: AlertsListTableProps) => { alert={selectedAlert} handleCancel={handleCancel} handleConfirm={handleConfirm} - isActive={isActive} + isEnabled={isEnabled} isLoading={isUpdating} isOpen={isDialogOpen} message={message} From f7d4c7118de427a6905793c643082c8d0368f916 Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Mon, 7 Apr 2025 13:52:24 +0530 Subject: [PATCH 06/17] Changed typography variant of confirmation dialog message --- .../CloudPulse/Alerts/AlertsLanding/AlertConfirmationDialog.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/manager/src/features/CloudPulse/Alerts/AlertsLanding/AlertConfirmationDialog.tsx b/packages/manager/src/features/CloudPulse/Alerts/AlertsLanding/AlertConfirmationDialog.tsx index 01f89164688..93f0cc1e7a2 100644 --- a/packages/manager/src/features/CloudPulse/Alerts/AlertsLanding/AlertConfirmationDialog.tsx +++ b/packages/manager/src/features/CloudPulse/Alerts/AlertsLanding/AlertConfirmationDialog.tsx @@ -85,7 +85,7 @@ export const AlertConfirmationDialog = React.memo( open={isOpen} title={title} > - {message} + {message} ); } From 8e5c22745ff59467e93017d1160e7587515f2b1a Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Mon, 7 Apr 2025 21:44:13 +0530 Subject: [PATCH 07/17] upcoming: [DI-24451] - Updated dialog message --- .../features/CloudPulse/Alerts/AlertsListing/AlertListTable.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/manager/src/features/CloudPulse/Alerts/AlertsListing/AlertListTable.tsx b/packages/manager/src/features/CloudPulse/Alerts/AlertsListing/AlertListTable.tsx index e7de2091467..22a981e7538 100644 --- a/packages/manager/src/features/CloudPulse/Alerts/AlertsListing/AlertListTable.tsx +++ b/packages/manager/src/features/CloudPulse/Alerts/AlertsListing/AlertListTable.tsx @@ -116,7 +116,7 @@ export const AlertsListTable = React.memo((props: AlertsListTableProps) => { isEnabled = selectedAlert.status !== 'disabled'; message = `Are you sure you want to ${ isEnabled ? 'disable' : 'enable' - } this alert for all assigned resources?`; + } this alert definition?`; title = `${isEnabled ? 'Disable' : 'Enable'} ${selectedAlert.label} Alert?`; } From dd1e664e3190cc82c78f353664cf99e71551f7c8 Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Tue, 8 Apr 2025 13:11:55 +0530 Subject: [PATCH 08/17] upcoming: [DI-24451] - Updated failing cypress test --- .../cypress/e2e/core/cloudpulse/alerts-listing-page.spec.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/manager/cypress/e2e/core/cloudpulse/alerts-listing-page.spec.ts b/packages/manager/cypress/e2e/core/cloudpulse/alerts-listing-page.spec.ts index 90d9498dd7b..99ac3312939 100644 --- a/packages/manager/cypress/e2e/core/cloudpulse/alerts-listing-page.spec.ts +++ b/packages/manager/cypress/e2e/core/cloudpulse/alerts-listing-page.spec.ts @@ -322,6 +322,7 @@ describe('Integration Tests for CloudPulse Alerts Listing Page', () => { }); ui.actionMenuItem.findByTitle(action).should('be.visible').click(); + ui.button.findByTitle(action).should('be.visible').click(); cy.wait(alias).then(({ response }) => { ui.toast.assertMessage(successMessage); From 1272ca3a004cb80328ee83a5268460ce1eb1a439 Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Tue, 8 Apr 2025 13:12:19 +0530 Subject: [PATCH 09/17] upcoming: [DI-24451] - Remove unused callback --- .../CloudPulse/Alerts/AlertsListing/AlertListTable.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/manager/src/features/CloudPulse/Alerts/AlertsListing/AlertListTable.tsx b/packages/manager/src/features/CloudPulse/Alerts/AlertsListing/AlertListTable.tsx index 22a981e7538..04f643271cf 100644 --- a/packages/manager/src/features/CloudPulse/Alerts/AlertsListing/AlertListTable.tsx +++ b/packages/manager/src/features/CloudPulse/Alerts/AlertsListing/AlertListTable.tsx @@ -65,10 +65,10 @@ export const AlertsListTable = React.memo((props: AlertsListTableProps) => { history.push(`${location.pathname}/edit/${serviceType}/${id}`); }; - const handleEnableDisable = React.useCallback((alert: Alert) => { + const handleEnableDisable = (alert: Alert) => { setSelectedAlert(alert); setIsDialogOpen(true); - }, []); + }; const handleCancel = React.useCallback(() => { setIsDialogOpen(false); From 6ba7b1c50a3e537aa90bb66552e398b1724aa378 Mon Sep 17 00:00:00 2001 From: agorthi Date: Mon, 7 Apr 2025 13:16:01 +0530 Subject: [PATCH 10/17] test: [DI-24452]-Cypress automation for User alerts - enable/disable Confirmation dialogue boxes --- .../cloudpulse/alerts-listing-page.spec.ts | 83 +++++++++++++------ 1 file changed, 59 insertions(+), 24 deletions(-) diff --git a/packages/manager/cypress/e2e/core/cloudpulse/alerts-listing-page.spec.ts b/packages/manager/cypress/e2e/core/cloudpulse/alerts-listing-page.spec.ts index 99ac3312939..60bc78fb138 100644 --- a/packages/manager/cypress/e2e/core/cloudpulse/alerts-listing-page.spec.ts +++ b/packages/manager/cypress/e2e/core/cloudpulse/alerts-listing-page.spec.ts @@ -63,6 +63,13 @@ const mockAlerts = [ updated: new Date(now.getTime() - 4 * 86400).toISOString(), }), ]; +interface AlertToggleOptions { + action: 'Disable' | 'Enable'; + alertName: string; + alias: string; + confirmationText: string; + successMessage: string; +} /** * @description @@ -305,12 +312,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') @@ -320,30 +328,57 @@ describe('Integration Tests for CloudPulse Alerts Listing Page', () => { .should('be.visible') .click(); }); - ui.actionMenuItem.findByTitle(action).should('be.visible').click(); - ui.button.findByTitle(action).should('be.visible').click(); - cy.wait(alias).then(({ response }) => { + // verify dialog title + cy.get('[data-qa-drawer-title]') + .should('be.visible') + .should('have.text', `${action} ${alertName} Alert?`); + + cy.get('[data-qa-drawer="true"]') + .find('h6') + .should('be.visible') + .should('have.text', confirmationText); + + ui.buttonGroup + .find() + .find('button') + .filter(`[label="${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<{ + action: 'Disable' | 'Enable'; + alertName: string; + alias: string; + }> = [ + { + 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 for all assigned entities?`, + successMessage: UPDATE_ALERT_SUCCESS_MESSAGE, + }); + }); }); }); From fc70e1b5f5717b1d54468572218e3c0be59c016b Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Tue, 8 Apr 2025 13:57:02 +0530 Subject: [PATCH 11/17] test: [DI-24451] - Updated test cases --- .../cloudpulse/alerts-listing-page.spec.ts | 2 +- .../AlertConfirmationDialog.test.tsx | 36 +++++++++---------- 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/packages/manager/cypress/e2e/core/cloudpulse/alerts-listing-page.spec.ts b/packages/manager/cypress/e2e/core/cloudpulse/alerts-listing-page.spec.ts index 60bc78fb138..04d406404e6 100644 --- a/packages/manager/cypress/e2e/core/cloudpulse/alerts-listing-page.spec.ts +++ b/packages/manager/cypress/e2e/core/cloudpulse/alerts-listing-page.spec.ts @@ -376,7 +376,7 @@ describe('Integration Tests for CloudPulse Alerts Listing Page', () => { action, alertName, alias, - confirmationText: `Are you sure you want to ${action.toLowerCase()} this alert for all assigned entities?`, + confirmationText: `Are you sure you want to ${action.toLowerCase()} this alert definition?`, successMessage: UPDATE_ALERT_SUCCESS_MESSAGE, }); }); diff --git a/packages/manager/src/features/CloudPulse/Alerts/AlertsLanding/AlertConfirmationDialog.test.tsx b/packages/manager/src/features/CloudPulse/Alerts/AlertsLanding/AlertConfirmationDialog.test.tsx index 2072e284d59..d3df0dd683e 100644 --- a/packages/manager/src/features/CloudPulse/Alerts/AlertsLanding/AlertConfirmationDialog.test.tsx +++ b/packages/manager/src/features/CloudPulse/Alerts/AlertsLanding/AlertConfirmationDialog.test.tsx @@ -9,10 +9,14 @@ 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', () => { - const message = `Are you sure you want to disable the alert for ${entityName}?`; - const title = `Disable ${alert.label} Alert?`; it('should show confirmation dialog', () => { const { getByTestId, getByText } = renderWithTheme( { handleConfirm={confirmFunction} isEnabled={true} isOpen={true} - message={message} - title={title} + message={messages.disableMessage} + title={messages.disableTitle} /> ); 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 message = `Are you sure you want to disable the alert for ${entityName}?`; - const title = `Disable ${alert.label} Alert?`; const { getByText } = renderWithTheme( { handleConfirm={confirmFunction} isEnabled={true} isOpen={true} - message={message} - title={title} + message={messages.disableMessage} + title={messages.disableTitle} /> ); @@ -54,8 +54,6 @@ describe('Alert confirmation dialog', () => { expect(confirmFunction).toBeCalledWith(alert, true); }); it('should show enable text', async () => { - const message = `Are you sure you want to enable the alert for ${entityName}?`; - const title = `Enable ${alert.label} Alert?`; const { getByTestId, getByText } = renderWithTheme( { handleConfirm={confirmFunction} isEnabled={false} isOpen={true} - message={message} - title={title} + message={messages.enableMessage} + title={messages.enableTitle} /> ); 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(); }); }); From 7163abcbf2d7bcee6b898e629eb1f759777685f4 Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Tue, 8 Apr 2025 14:13:53 +0530 Subject: [PATCH 12/17] upcoming: [DI-24451] - Removed title from from alert confirmation dialog --- .../AlertConfirmationDialog.test.tsx | 3 --- .../AlertsLanding/AlertConfirmationDialog.tsx | 8 +------- .../Alerts/AlertsListing/AlertListTable.tsx | 18 ++++-------------- .../AlertInformationActionTable.tsx | 15 +++------------ 4 files changed, 8 insertions(+), 36 deletions(-) diff --git a/packages/manager/src/features/CloudPulse/Alerts/AlertsLanding/AlertConfirmationDialog.test.tsx b/packages/manager/src/features/CloudPulse/Alerts/AlertsLanding/AlertConfirmationDialog.test.tsx index d3df0dd683e..6a469f94974 100644 --- a/packages/manager/src/features/CloudPulse/Alerts/AlertsLanding/AlertConfirmationDialog.test.tsx +++ b/packages/manager/src/features/CloudPulse/Alerts/AlertsLanding/AlertConfirmationDialog.test.tsx @@ -26,7 +26,6 @@ describe('Alert confirmation dialog', () => { isEnabled={true} isOpen={true} message={messages.disableMessage} - title={messages.disableTitle} /> ); @@ -43,7 +42,6 @@ describe('Alert confirmation dialog', () => { isEnabled={true} isOpen={true} message={messages.disableMessage} - title={messages.disableTitle} /> ); @@ -62,7 +60,6 @@ describe('Alert confirmation dialog', () => { isEnabled={false} isOpen={true} message={messages.enableMessage} - title={messages.enableTitle} /> ); diff --git a/packages/manager/src/features/CloudPulse/Alerts/AlertsLanding/AlertConfirmationDialog.tsx b/packages/manager/src/features/CloudPulse/Alerts/AlertsLanding/AlertConfirmationDialog.tsx index 93f0cc1e7a2..5138633d40a 100644 --- a/packages/manager/src/features/CloudPulse/Alerts/AlertsLanding/AlertConfirmationDialog.tsx +++ b/packages/manager/src/features/CloudPulse/Alerts/AlertsLanding/AlertConfirmationDialog.tsx @@ -42,11 +42,6 @@ interface AlertConfirmationDialogProps { * Message to be displayed in the confirmation dialog */ message: string; - - /** - * Title of the confirmation dialog - */ - title: string; } export const AlertConfirmationDialog = React.memo( @@ -59,7 +54,6 @@ export const AlertConfirmationDialog = React.memo( isLoading = false, isOpen, message, - title, } = props; const actionsPanel = ( @@ -83,7 +77,7 @@ export const AlertConfirmationDialog = React.memo( data-testid="confirmation-dialog" onClose={handleCancel} open={isOpen} - title={title} + title={`${isEnabled ? 'Disable' : 'Enable'} ${alert.label} Alert?`} > {message} diff --git a/packages/manager/src/features/CloudPulse/Alerts/AlertsListing/AlertListTable.tsx b/packages/manager/src/features/CloudPulse/Alerts/AlertsListing/AlertListTable.tsx index 04f643271cf..533d68d59c8 100644 --- a/packages/manager/src/features/CloudPulse/Alerts/AlertsListing/AlertListTable.tsx +++ b/packages/manager/src/features/CloudPulse/Alerts/AlertsListing/AlertListTable.tsx @@ -108,18 +108,7 @@ export const AlertsListTable = React.memo((props: AlertsListTableProps) => { [editAlertDefinition] ); - let isEnabled = false; - - let message = ''; - let title = ''; - if (isDialogOpen) { - isEnabled = selectedAlert.status !== 'disabled'; - message = `Are you sure you want to ${ - isEnabled ? 'disable' : 'enable' - } this alert definition?`; - - title = `${isEnabled ? 'Disable' : 'Enable'} ${selectedAlert.label} Alert?`; - } + const isEnabled = selectedAlert.status !== 'disabled'; return ( <> @@ -219,14 +208,15 @@ export const AlertsListTable = React.memo((props: AlertsListTableProps) => { )} ); diff --git a/packages/manager/src/features/CloudPulse/Alerts/ContextualView/AlertInformationActionTable.tsx b/packages/manager/src/features/CloudPulse/Alerts/ContextualView/AlertInformationActionTable.tsx index a6b293d7e79..aff0cdd8db3 100644 --- a/packages/manager/src/features/CloudPulse/Alerts/ContextualView/AlertInformationActionTable.tsx +++ b/packages/manager/src/features/CloudPulse/Alerts/ContextualView/AlertInformationActionTable.tsx @@ -121,16 +121,7 @@ export const AlertInformationActionTable = ( setSelectedAlert(alert); }; - let isEnabled = false; - - let message = ''; - let title = ''; - if (isDialogOpen) { - isEnabled = selectedAlert.entity_ids?.includes(entityId) ?? false; - message = `Are you sure you want to - ${isEnabled ? 'disable' : 'enable'} the alert for ${entityName}?`; - title = `${isEnabled ? 'Disable' : 'Enable'} ${selectedAlert.label} Alert?`; - } + const isEnabled = selectedAlert.entity_ids?.includes(entityId) ?? false; return ( <> @@ -203,14 +194,14 @@ export const AlertInformationActionTable = ( )} ); From 5e8997149b006389396fadf3530dae4fae69a700 Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Tue, 8 Apr 2025 14:34:51 +0530 Subject: [PATCH 13/17] test: [DI-24451] - Updated cypress test --- .../e2e/core/cloudpulse/alerts-listing-page.spec.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/manager/cypress/e2e/core/cloudpulse/alerts-listing-page.spec.ts b/packages/manager/cypress/e2e/core/cloudpulse/alerts-listing-page.spec.ts index 04d406404e6..61a2ec464ae 100644 --- a/packages/manager/cypress/e2e/core/cloudpulse/alerts-listing-page.spec.ts +++ b/packages/manager/cypress/e2e/core/cloudpulse/alerts-listing-page.spec.ts @@ -335,7 +335,7 @@ describe('Integration Tests for CloudPulse Alerts Listing Page', () => { .should('be.visible') .should('have.text', `${action} ${alertName} Alert?`); - cy.get('[data-qa-drawer="true"]') + cy.get('[data-qa-drawer]') .find('h6') .should('be.visible') .should('have.text', confirmationText); @@ -353,11 +353,7 @@ describe('Integration Tests for CloudPulse Alerts Listing Page', () => { }); }; // Disable "Alert-1" - const actions: Array<{ - action: 'Disable' | 'Enable'; - alertName: string; - alias: string; - }> = [ + const actions: Array> = [ { action: 'Disable', alertName: 'Alert-1', From 11a0f340ca1c4bd10d9ffb4069ee264255671479 Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Tue, 8 Apr 2025 15:01:50 +0530 Subject: [PATCH 14/17] typecheck fix --- .../cypress/e2e/core/cloudpulse/alerts-listing-page.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/manager/cypress/e2e/core/cloudpulse/alerts-listing-page.spec.ts b/packages/manager/cypress/e2e/core/cloudpulse/alerts-listing-page.spec.ts index 61a2ec464ae..9b43a5fb84b 100644 --- a/packages/manager/cypress/e2e/core/cloudpulse/alerts-listing-page.spec.ts +++ b/packages/manager/cypress/e2e/core/cloudpulse/alerts-listing-page.spec.ts @@ -353,7 +353,7 @@ describe('Integration Tests for CloudPulse Alerts Listing Page', () => { }); }; // Disable "Alert-1" - const actions: Array> = [ + const actions: Array> = [ { action: 'Disable', alertName: 'Alert-1', From 95d30c6cf9965cdd2326d399133e62cf3dbacd77 Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Tue, 8 Apr 2025 15:04:06 +0530 Subject: [PATCH 15/17] added changeset --- .../.changeset/pr-11981-upcoming-features-1744104834195.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 packages/manager/.changeset/pr-11981-upcoming-features-1744104834195.md diff --git a/packages/manager/.changeset/pr-11981-upcoming-features-1744104834195.md b/packages/manager/.changeset/pr-11981-upcoming-features-1744104834195.md new file mode 100644 index 00000000000..016235f78df --- /dev/null +++ b/packages/manager/.changeset/pr-11981-upcoming-features-1744104834195.md @@ -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)) From 039f42d286a745a27ea118ad3f45a4ce9a9a7c69 Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Tue, 8 Apr 2025 16:26:13 +0530 Subject: [PATCH 16/17] test: [DI-24451] - Updated interface --- .../e2e/core/cloudpulse/alerts-listing-page.spec.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/manager/cypress/e2e/core/cloudpulse/alerts-listing-page.spec.ts b/packages/manager/cypress/e2e/core/cloudpulse/alerts-listing-page.spec.ts index 9b43a5fb84b..e37ef79b7f3 100644 --- a/packages/manager/cypress/e2e/core/cloudpulse/alerts-listing-page.spec.ts +++ b/packages/manager/cypress/e2e/core/cloudpulse/alerts-listing-page.spec.ts @@ -63,10 +63,14 @@ const mockAlerts = [ updated: new Date(now.getTime() - 4 * 86400).toISOString(), }), ]; -interface AlertToggleOptions { + +interface AlertActionOptions { action: 'Disable' | 'Enable'; alertName: string; alias: string; +} + +interface AlertToggleOptions extends AlertActionOptions { confirmationText: string; successMessage: string; } @@ -353,7 +357,7 @@ describe('Integration Tests for CloudPulse Alerts Listing Page', () => { }); }; // Disable "Alert-1" - const actions: Array> = [ + const actions: Array = [ { action: 'Disable', alertName: 'Alert-1', From fe39e2d6ad38cff138457f59202e5ba1bc56baec Mon Sep 17 00:00:00 2001 From: nikhagra-akamai Date: Tue, 8 Apr 2025 19:03:19 +0530 Subject: [PATCH 17/17] test: [DI-24451] - Updated test case --- .../cloudpulse/alerts-listing-page.spec.ts | 25 ++++++++----------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/packages/manager/cypress/e2e/core/cloudpulse/alerts-listing-page.spec.ts b/packages/manager/cypress/e2e/core/cloudpulse/alerts-listing-page.spec.ts index e37ef79b7f3..8481c24768f 100644 --- a/packages/manager/cypress/e2e/core/cloudpulse/alerts-listing-page.spec.ts +++ b/packages/manager/cypress/e2e/core/cloudpulse/alerts-listing-page.spec.ts @@ -335,22 +335,17 @@ describe('Integration Tests for CloudPulse Alerts Listing Page', () => { ui.actionMenuItem.findByTitle(action).should('be.visible').click(); // verify dialog title - cy.get('[data-qa-drawer-title]') + ui.dialog + .findByTitle(`${action} ${alertName} Alert?`) .should('be.visible') - .should('have.text', `${action} ${alertName} Alert?`); - - cy.get('[data-qa-drawer]') - .find('h6') - .should('be.visible') - .should('have.text', confirmationText); - - ui.buttonGroup - .find() - .find('button') - .filter(`[label="${action}"]`) - .should('be.visible') - .should('be.enabled') - .click(); + .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);