diff --git a/src/apps/work/src/lib/components/ProjectBillingAccountExpiredNotice/ProjectBillingAccountExpiredNotice.spec.tsx b/src/apps/work/src/lib/components/ProjectBillingAccountExpiredNotice/ProjectBillingAccountExpiredNotice.spec.tsx index 1f19af869..7e10429d1 100644 --- a/src/apps/work/src/lib/components/ProjectBillingAccountExpiredNotice/ProjectBillingAccountExpiredNotice.spec.tsx +++ b/src/apps/work/src/lib/components/ProjectBillingAccountExpiredNotice/ProjectBillingAccountExpiredNotice.spec.tsx @@ -229,7 +229,7 @@ describe('ProjectBillingAccountExpiredNotice', () => { .toBeNull() }) - it('hides the inline member payment balance but keeps billing account modal access for copilots ' + it('hides the inline member payment balance and billing account modal access for copilots ' + 'when disabled', () => { mockedUseFetchBillingAccountDetails.mockReturnValue({ billingAccountDetails: { @@ -255,14 +255,13 @@ describe('ProjectBillingAccountExpiredNotice', () => { .toBeNull() expect(screen.queryByText('$750 / $1,000 spent')) .toBeNull() - fireEvent.click(screen.getByRole('button', { + expect(screen.queryByRole('button', { name: 'View billing account details', })) - - expect(screen.getByRole('dialog') - .textContent) - .toContain('Billing account details for 80001063') + .toBeNull() + expect(screen.queryByRole('dialog')) + .toBeNull() expect(mockedUseFetchBillingAccountDetails) - .toHaveBeenCalledWith('80001063') + .toHaveBeenCalledWith(undefined) }) }) diff --git a/src/apps/work/src/lib/components/ProjectBillingAccountExpiredNotice/ProjectBillingAccountExpiredNotice.tsx b/src/apps/work/src/lib/components/ProjectBillingAccountExpiredNotice/ProjectBillingAccountExpiredNotice.tsx index 96a3c130f..12f2818a2 100644 --- a/src/apps/work/src/lib/components/ProjectBillingAccountExpiredNotice/ProjectBillingAccountExpiredNotice.tsx +++ b/src/apps/work/src/lib/components/ProjectBillingAccountExpiredNotice/ProjectBillingAccountExpiredNotice.tsx @@ -349,6 +349,7 @@ export const ProjectBillingAccountExpiredNotice: FC ) : undefined const billingAccountModal = renderBillingAccountModal( billingAccountDetailsData, - isModalOpen, + showDetailsButton && isModalOpen, handleCloseModal, props.projectId, showMemberPaymentsRemainingInModal, diff --git a/src/apps/work/src/lib/components/ProjectsTable/ProjectsTable.spec.tsx b/src/apps/work/src/lib/components/ProjectsTable/ProjectsTable.spec.tsx index 6fe404d86..8870ba76f 100644 --- a/src/apps/work/src/lib/components/ProjectsTable/ProjectsTable.spec.tsx +++ b/src/apps/work/src/lib/components/ProjectsTable/ProjectsTable.spec.tsx @@ -320,7 +320,7 @@ describe('ProjectsTable', () => { .toBeNull() }) - it('hides inline payment amounts but keeps billing details available for copilot project rows ' + it('hides inline payment amounts and billing details for copilot project rows ' + 'when disabled', () => { mockedUseFetchBillingAccounts.mockReturnValue({ billingAccounts: [ @@ -366,12 +366,11 @@ describe('ProjectsTable', () => { .toBeNull() expect(screen.queryByText('$750 / $1,000 spent')) .toBeNull() - fireEvent.click(screen.getAllByRole('button', { + expect(screen.queryByRole('button', { name: 'View billing account details', - })[0]) - - expect(screen.getByRole('dialog') - .textContent) - .toContain('Billing account details for 80001063') + })) + .toBeNull() + expect(screen.queryByRole('dialog')) + .toBeNull() }) }) diff --git a/src/apps/work/src/lib/components/ProjectsTable/ProjectsTable.tsx b/src/apps/work/src/lib/components/ProjectsTable/ProjectsTable.tsx index 5de3da688..19dfe8896 100644 --- a/src/apps/work/src/lib/components/ProjectsTable/ProjectsTable.tsx +++ b/src/apps/work/src/lib/components/ProjectsTable/ProjectsTable.tsx @@ -268,12 +268,16 @@ interface RenderProjectBillingAccountModalParams { * Resolves whether the billing-account details hook should fetch modal data. * * @param isModalOpen Whether the row details modal has been opened. + * @param showDetailsButton Whether this user may open billing-account details. * @returns `true` when the modal feature is enabled and data should be fetched. */ function canFetchProjectBillingAccountDetails( isModalOpen: boolean, + showDetailsButton: boolean, ): boolean { - return BILLING_ACCOUNT_DETAILS_MODAL_ENABLED && isModalOpen + return BILLING_ACCOUNT_DETAILS_MODAL_ENABLED + && showDetailsButton + && isModalOpen } /** @@ -350,13 +354,15 @@ function renderProjectBillingAccountBudget( * * @param billingAccountId Normalized billing-account id for the current row. * @param onOpen Open handler for the row modal. + * @param showDetailsButton Whether this user may open billing-account details. * @returns The details button, or `undefined` when unavailable. */ function renderProjectBillingAccountDetailsButton( billingAccountId: string | undefined, onOpen: () => void, + showDetailsButton: boolean, ): JSX.Element | undefined { - if (!BILLING_ACCOUNT_DETAILS_MODAL_ENABLED || !billingAccountId) { + if (!BILLING_ACCOUNT_DETAILS_MODAL_ENABLED || !showDetailsButton || !billingAccountId) { return undefined } @@ -413,8 +419,9 @@ const ProjectBillingAccountCell: FC = ( const [isModalOpen, setIsModalOpen] = useState(false) const normalizedBillingAccountId = normalizeOptionalString(props.project.billingAccountId) || normalizeOptionalString(props.billingAccount?.id) + const showDetailsButton = props.showPaymentAmounts const billingAccountDetailsResult: UseFetchBillingAccountDetailsResult = useFetchBillingAccountDetails( - canFetchProjectBillingAccountDetails(isModalOpen) + canFetchProjectBillingAccountDetails(isModalOpen, showDetailsButton) ? normalizedBillingAccountId : undefined, ) @@ -438,10 +445,11 @@ const ProjectBillingAccountCell: FC = ( const billingAccountDetailsButton = renderProjectBillingAccountDetailsButton( normalizedBillingAccountId, handleOpenModal, + showDetailsButton, ) const billingAccountModal = renderProjectBillingAccountModal({ billingAccountDetails: billingAccountDetailsResult.billingAccountDetails, - isModalOpen, + isModalOpen: showDetailsButton && isModalOpen, onClose: handleCloseModal, projectId: props.project.id, showMemberPaymentsRemaining: props.showMemberPaymentsRemainingInModal,