From f5955393ee0c95f49ecab043a8be7d851365e28c Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 26 Aug 2026 08:55:50 +0000 Subject: [PATCH 1/2] Bug-1995794: Disable retrigger dropdown when there are no runs Disable the Base and New retrigger count selects independently when there are no retriggerable job ids for that side, and default a disabled select to 0 so it does not look like jobs will start. --- .../CompareResults/Retrigger.test.tsx | 57 +++++++++++++++++++ .../Retrigger/RetriggerButton.tsx | 2 + .../Retrigger/RetriggerConfigModal.tsx | 21 +++++-- 3 files changed, 76 insertions(+), 4 deletions(-) diff --git a/src/__tests__/CompareResults/Retrigger.test.tsx b/src/__tests__/CompareResults/Retrigger.test.tsx index 302972e45..4df03f040 100644 --- a/src/__tests__/CompareResults/Retrigger.test.tsx +++ b/src/__tests__/CompareResults/Retrigger.test.tsx @@ -267,6 +267,63 @@ describe('Retrigger', () => { expect(new MockedHooks().triggerHook).toHaveBeenCalled(); }); + + async function openRetriggerConfigModal( + compareResult: typeof result = result, + ) { + setUpUserCredentials(); + render(); + + const openModalButton = await screen.findByRole('button', { + name: 'retrigger jobs', + }); + + const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime }); + await user.click(openModalButton); + + return { + baseSelect: await screen.findByLabelText('Base'), + newSelect: await screen.findByLabelText('New'), + }; + } + + it('should disable the Base dropdown when there are no base retriggerable jobs', async () => { + const { baseSelect, newSelect } = await openRetriggerConfigModal({ + ...result, + base_retriggerable_job_ids: [], + }); + + // MUI Select uses a combobox div with aria-disabled rather than native disabled. + expect(baseSelect).toHaveAttribute('aria-disabled', 'true'); + expect(baseSelect).toHaveTextContent('0'); + expect(newSelect).not.toHaveAttribute('aria-disabled', 'true'); + expect(newSelect).toHaveTextContent('5'); + }); + + it('should disable the New dropdown when there are no new retriggerable jobs', async () => { + const { baseSelect, newSelect } = await openRetriggerConfigModal({ + ...result, + new_retriggerable_job_ids: [], + }); + + expect(baseSelect).not.toHaveAttribute('aria-disabled', 'true'); + expect(baseSelect).toHaveTextContent('5'); + expect(newSelect).toHaveAttribute('aria-disabled', 'true'); + expect(newSelect).toHaveTextContent('0'); + }); + + it('should disable both dropdowns when there are no retriggerable jobs', async () => { + const { baseSelect, newSelect } = await openRetriggerConfigModal({ + ...result, + base_retriggerable_job_ids: [], + new_retriggerable_job_ids: [], + }); + + expect(baseSelect).toHaveAttribute('aria-disabled', 'true'); + expect(baseSelect).toHaveTextContent('0'); + expect(newSelect).toHaveAttribute('aria-disabled', 'true'); + expect(newSelect).toHaveTextContent('0'); + }); }); describe('Retrigger in Subtests view', () => { diff --git a/src/components/CompareResults/Retrigger/RetriggerButton.tsx b/src/components/CompareResults/Retrigger/RetriggerButton.tsx index 520be1425..7c4f5bc96 100644 --- a/src/components/CompareResults/Retrigger/RetriggerButton.tsx +++ b/src/components/CompareResults/Retrigger/RetriggerButton.tsx @@ -210,6 +210,8 @@ export function RetriggerButton({ result, variant }: RetriggerButtonProps) { open={status === 'retrigger-modal'} onClose={() => setStatus('pending')} onRetriggerClick={onRetriggerConfirm} + hasBaseJobs={baseRetriggerableJobIds.length > 0} + hasNewJobs={newRetriggerableJobIds.length > 0} /> ); diff --git a/src/components/CompareResults/Retrigger/RetriggerConfigModal.tsx b/src/components/CompareResults/Retrigger/RetriggerConfigModal.tsx index 32220adb2..e9334b0be 100644 --- a/src/components/CompareResults/Retrigger/RetriggerConfigModal.tsx +++ b/src/components/CompareResults/Retrigger/RetriggerConfigModal.tsx @@ -16,17 +16,20 @@ const retriggerStrings = Strings.components.retrigger.config; function RetriggerCountSelect({ prefix, label, + disabled = false, }: { prefix: string; label: string; + disabled?: boolean; }) { return ( - + {label} @@ -101,7 +105,12 @@ export function RetriggerConfigModal(props: RetriggerModalProps) { ml: 'auto', }} > - +