From a487a55c8782be4eb191b1cf455a356f3c0d7d77 Mon Sep 17 00:00:00 2001 From: jekabskarklins Date: Tue, 9 Dec 2025 15:24:57 +0100 Subject: [PATCH 1/5] fix: implement confirmation window for multi-select actions in ProposalTableOfficer --- .../proposal/ProposalTableOfficer.tsx | 65 ++++++++++++++----- 1 file changed, 49 insertions(+), 16 deletions(-) diff --git a/apps/frontend/src/components/proposal/ProposalTableOfficer.tsx b/apps/frontend/src/components/proposal/ProposalTableOfficer.tsx index bb602281f8..dcf49b0f7d 100644 --- a/apps/frontend/src/components/proposal/ProposalTableOfficer.tsx +++ b/apps/frontend/src/components/proposal/ProposalTableOfficer.tsx @@ -14,6 +14,7 @@ import GetAppIcon from '@mui/icons-material/GetApp'; import GridOnIcon from '@mui/icons-material/GridOn'; import GroupWork from '@mui/icons-material/GroupWork'; import ReduceCapacityIcon from '@mui/icons-material/ReduceCapacity'; +import Warning from '@mui/icons-material/Warning'; import { IconButton, Tooltip } from '@mui/material'; import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; @@ -462,6 +463,29 @@ const ProposalTableOfficer = ({ searchParams.getAll('selection').includes(item.primaryKey.toString()) ); + const runWithMultiSelectConfirm = (action: () => void) => { + const selectedCount = getSelectedProposalPks().length; + + if (selectedCount > 1) { + confirm(action, { + title: 'Are you sure? Multiple proposals selected!', + description: ( + + + + {selectedCount} proposals are selected. This action will + affect all selected proposals. Are you sure you want to proceed? + + + ), + confirmationText: 'Yes, proceed', + cancellationText: 'Cancel', + })(); + } else { + action(); + } + }; + const handleClose = (selectedOption: string) => { const firstSelectedProposalTitle = getSelectedProposalsData()[0].title; if (selectedOption === PdfDownloadMenuOption.PDF) { @@ -780,16 +804,18 @@ const ProposalTableOfficer = ({ { icon: FileCopy, tooltip: 'Clone proposals to call', - onClick: () => { - setOpenCallSelection(true); - }, + onClick: () => + runWithMultiSelectConfirm(() => { + setOpenCallSelection(true); + }), position: 'toolbarOnSelect', }, { icon: GetAppIconComponent, tooltip: 'Download proposals', onClick: (event): void => { - handleDownloadActionClick(event); + runWithMultiSelectConfirm(() => handleDownloadActionClick(event)) + }, position: 'toolbarOnSelect', }, @@ -797,13 +823,15 @@ const ProposalTableOfficer = ({ icon: ExportIcon, tooltip: 'Export proposals in Excel', onClick: (): void => { - downloadXLSXProposal( - searchParams - .getAll('selection') - .filter((item): item is string => !!item) - .map((item) => +item), - selectedProposalsData?.[0].title - ); + runWithMultiSelectConfirm(() => { + downloadXLSXProposal( + searchParams + .getAll('selection') + .filter((item): item is string => !!item) + .map((item) => +item), + selectedProposalsData?.[0].title + ); + }); }, position: 'toolbarOnSelect', }, @@ -817,8 +845,7 @@ const ProposalTableOfficer = ({ }, { title: 'Delete proposals', - description: - 'This action will delete proposals and all data associated with them.', + description: `This action will delete ${selectedProposalsData.length} proposal(s) and all data associated with them.`, } )(); }, @@ -828,7 +855,9 @@ const ProposalTableOfficer = ({ icon: ChangeProposalStatusIcon, tooltip: 'Change proposal status', onClick: () => { - setOpenChangeProposalStatus(true); + runWithMultiSelectConfirm(() => { + setOpenChangeProposalStatus(true); + }); }, position: 'toolbarOnSelect', }, @@ -911,7 +940,9 @@ const ProposalTableOfficer = ({ tableActions.push({ icon: ReduceCapacityIconComponent, tooltip: 'Reassign selected Techniqual Reviews', - onClick: handleBulkTechnicalReviewsReassign, + onClick: () => { + runWithMultiSelectConfirm(handleBulkTechnicalReviewsReassign); + }, position: 'toolbarOnSelect', }); @@ -920,7 +951,9 @@ const ProposalTableOfficer = ({ icon: GroupWorkIcon, tooltip: 'Assign proposals to FAP', onClick: () => { - setOpenAssignment(true); + runWithMultiSelectConfirm(() => { + setOpenAssignment(true); + }); }, position: 'toolbarOnSelect', }); From 09586ddf095bc187f069c7a1937937631a35c6a1 Mon Sep 17 00:00:00 2001 From: jekabskarklins Date: Tue, 9 Dec 2025 16:09:22 +0100 Subject: [PATCH 2/5] fix: simplify confirmation handling for proposal actions in ProposalTableOfficer --- .../proposal/ProposalTableOfficer.tsx | 26 ++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/apps/frontend/src/components/proposal/ProposalTableOfficer.tsx b/apps/frontend/src/components/proposal/ProposalTableOfficer.tsx index dcf49b0f7d..efa141e1eb 100644 --- a/apps/frontend/src/components/proposal/ProposalTableOfficer.tsx +++ b/apps/frontend/src/components/proposal/ProposalTableOfficer.tsx @@ -474,7 +474,8 @@ const ProposalTableOfficer = ({ {selectedCount} proposals are selected. This action will - affect all selected proposals. Are you sure you want to proceed? + run on all of the selected proposals. Are you sure you want to + proceed? ), @@ -814,8 +815,7 @@ const ProposalTableOfficer = ({ icon: GetAppIconComponent, tooltip: 'Download proposals', onClick: (event): void => { - runWithMultiSelectConfirm(() => handleDownloadActionClick(event)) - + handleDownloadActionClick(event); }, position: 'toolbarOnSelect', }, @@ -823,15 +823,13 @@ const ProposalTableOfficer = ({ icon: ExportIcon, tooltip: 'Export proposals in Excel', onClick: (): void => { - runWithMultiSelectConfirm(() => { - downloadXLSXProposal( - searchParams - .getAll('selection') - .filter((item): item is string => !!item) - .map((item) => +item), - selectedProposalsData?.[0].title - ); - }); + downloadXLSXProposal( + searchParams + .getAll('selection') + .filter((item): item is string => !!item) + .map((item) => +item), + selectedProposalsData?.[0].title + ); }, position: 'toolbarOnSelect', }, @@ -855,9 +853,7 @@ const ProposalTableOfficer = ({ icon: ChangeProposalStatusIcon, tooltip: 'Change proposal status', onClick: () => { - runWithMultiSelectConfirm(() => { - setOpenChangeProposalStatus(true); - }); + setOpenChangeProposalStatus(true); }, position: 'toolbarOnSelect', }, From 182e529cd8211c981f8abe6b7536bc6b3b5b0760 Mon Sep 17 00:00:00 2001 From: jekabskarklins Date: Wed, 10 Dec 2025 14:56:03 +0100 Subject: [PATCH 3/5] fix: remove unnecessary confirmation for assignment action in ProposalTableOfficer --- .../frontend/src/components/proposal/ProposalTableOfficer.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/apps/frontend/src/components/proposal/ProposalTableOfficer.tsx b/apps/frontend/src/components/proposal/ProposalTableOfficer.tsx index efa141e1eb..5d0564bf50 100644 --- a/apps/frontend/src/components/proposal/ProposalTableOfficer.tsx +++ b/apps/frontend/src/components/proposal/ProposalTableOfficer.tsx @@ -947,9 +947,7 @@ const ProposalTableOfficer = ({ icon: GroupWorkIcon, tooltip: 'Assign proposals to FAP', onClick: () => { - runWithMultiSelectConfirm(() => { - setOpenAssignment(true); - }); + setOpenAssignment(true); }, position: 'toolbarOnSelect', }); From 1701b9ecdb640b27ecac151fdd6e454b076f84cc Mon Sep 17 00:00:00 2001 From: jekabskarklins Date: Wed, 10 Dec 2025 14:57:37 +0100 Subject: [PATCH 4/5] fix: add confirmation click for bulk reassign reviews in instrument tests --- apps/e2e/cypress/e2e/instruments.cy.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/e2e/cypress/e2e/instruments.cy.ts b/apps/e2e/cypress/e2e/instruments.cy.ts index 351ca7016f..87b4fcbd65 100644 --- a/apps/e2e/cypress/e2e/instruments.cy.ts +++ b/apps/e2e/cypress/e2e/instruments.cy.ts @@ -642,6 +642,8 @@ context('Instrument tests', () => { cy.get('[data-cy="bulk-reassign-reviews"]').click(); + cy.get('[data-cy="confirm-ok"]').click(); + cy.get('@createdProposal2Id').then((proposalId) => { cy.get('[data-cy="multi-instrument-alert"]').contains(`${proposalId}`); }); From aeca1e8213a7808d43e3dd22b367d2f213a0fb54 Mon Sep 17 00:00:00 2001 From: jekabskarklins Date: Wed, 10 Dec 2025 15:38:01 +0100 Subject: [PATCH 5/5] fix: ensure confirmation click is properly handled in bulk reassign reviews --- apps/e2e/cypress/e2e/instruments.cy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/e2e/cypress/e2e/instruments.cy.ts b/apps/e2e/cypress/e2e/instruments.cy.ts index 87b4fcbd65..5916562255 100644 --- a/apps/e2e/cypress/e2e/instruments.cy.ts +++ b/apps/e2e/cypress/e2e/instruments.cy.ts @@ -642,7 +642,7 @@ context('Instrument tests', () => { cy.get('[data-cy="bulk-reassign-reviews"]').click(); - cy.get('[data-cy="confirm-ok"]').click(); + cy.get('[data-cy="confirm-ok"]').click(); cy.get('@createdProposal2Id').then((proposalId) => { cy.get('[data-cy="multi-instrument-alert"]').contains(`${proposalId}`);