diff --git a/frontend/src/layouts/MainLayout/components/SupplierBalance.jsx b/frontend/src/layouts/MainLayout/components/SupplierBalance.jsx index ff0190fbc..943a39700 100644 --- a/frontend/src/layouts/MainLayout/components/SupplierBalance.jsx +++ b/frontend/src/layouts/MainLayout/components/SupplierBalance.jsx @@ -19,7 +19,9 @@ const SupplierBalance = () => { const { data: orgBalance } = useCurrentOrgBalance() const formattedTotalBalance = orgBalance?.totalBalance != null - ? numberFormatter({ value: orgBalance.totalBalance }) + ? numberFormatter({ + value: orgBalance.totalBalance - Math.abs(orgBalance.reservedBalance) + }) : 'N/A' const formattedReservedBalance = orgBalance?.reservedBalance != null diff --git a/frontend/src/views/Dashboard/components/cards/bceid/OrgBalanceCard.jsx b/frontend/src/views/Dashboard/components/cards/bceid/OrgBalanceCard.jsx index 0b1315e46..fc13f5696 100644 --- a/frontend/src/views/Dashboard/components/cards/bceid/OrgBalanceCard.jsx +++ b/frontend/src/views/Dashboard/components/cards/bceid/OrgBalanceCard.jsx @@ -35,6 +35,9 @@ const OrgBalanceCard = () => { orgBalance.reservedBalance ).toLocaleString() + const availableCredits = + orgBalance.totalBalance - Math.abs(orgBalance.reservedBalance) + return ( <> { style={{ fontSize: '32px', color: '#578260', marginBottom: '-4px' }} component="span" > - {orgBalance.totalBalance.toLocaleString()} + {availableCredits.toLocaleString()} { style={{ fontSize: '32px', color: '#578260', marginBottom: '-2px' }} component="span" > - {numberFormatter(selectedOrganization.totalBalance)} + {numberFormatter( + selectedOrganization.totalBalance - + Math.abs(selectedOrganization.reservedBalance) + )} { it('renders correctly with default values', () => { render(, { wrapper }) - expect(screen.getByText('2,500')).toBeInTheDocument() // Initial total balance + expect(screen.getByText('2,000')).toBeInTheDocument() // Initial total balance expect(screen.getByText('compliance units')).toBeInTheDocument() expect(screen.getByText('(500 in reserve)')).toBeInTheDocument() // Initial reserved balance }) @@ -51,7 +51,7 @@ describe('OrganizationsSummaryCards', () => { fireEvent.mouseDown(select) fireEvent.click(screen.getByRole('option', { name: 'Org A' })) // Select All organizations - expect(screen.getByText('1,000')).toBeInTheDocument() // Total balance for Org A + expect(screen.getByText('800')).toBeInTheDocument() // Total balance for Org A expect(screen.getByText('(200 in reserve)')).toBeInTheDocument() // Reserved balance for Org A }) @@ -65,7 +65,7 @@ describe('OrganizationsSummaryCards', () => { ) // Select All organizations const totalBalance = mockOrganizations.reduce( - (total, org) => total + org.totalBalance, + (total, org) => total + org.totalBalance - org.reservedBalance, 0 ) const totalReserved = mockOrganizations.reduce( diff --git a/frontend/src/views/Organizations/Organizations.jsx b/frontend/src/views/Organizations/Organizations.jsx index bca77d4fa..1c4b26cd9 100644 --- a/frontend/src/views/Organizations/Organizations.jsx +++ b/frontend/src/views/Organizations/Organizations.jsx @@ -1,21 +1,16 @@ -// mui components import BCAlert from '@/components/BCAlert' import BCBox from '@/components/BCBox' import BCButton from '@/components/BCButton' import BCTypography from '@/components/BCTypography' import BCDataGridServer from '@/components/BCDataGrid/BCDataGridServer' import { Stack } from '@mui/material' -// Icons import { faCirclePlus } from '@fortawesome/free-solid-svg-icons' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -// Internal components import { organizationsColDefs } from './ViewOrganization/_schema' -// react components -import { ROUTES, apiRoutes } from '@/constants/routes' +import { apiRoutes, ROUTES } from '@/constants/routes' import { useCallback, useEffect, useMemo, useRef, useState } from 'react' import { useLocation, useNavigate } from 'react-router-dom' import { useTranslation } from 'react-i18next' -// Services import { DownloadButton } from '@/components/DownloadButton' import { useApiService } from '@/services/useApiService' import { roles } from '@/constants/roles' @@ -25,9 +20,9 @@ import { LinkRenderer } from '@/utils/grid/cellRenderers.jsx' export const Organizations = () => { const { t } = useTranslation(['common', 'org']) const gridRef = useRef() - const [gridKey, setGridKey] = useState(`organizations-grid`) + const [gridKey, setGridKey] = useState('organizations-grid') const handleGridKey = useCallback(() => { - setGridKey(`organizations-grid`) + setGridKey('organizations-grid') }, []) const gridOptions = { overlayNoRowsTemplate: t('org:noOrgsFound') diff --git a/frontend/src/views/Organizations/ViewOrganization/_schema.js b/frontend/src/views/Organizations/ViewOrganization/_schema.js index 95625fe20..9285cc85e 100644 --- a/frontend/src/views/Organizations/ViewOrganization/_schema.js +++ b/frontend/src/views/Organizations/ViewOrganization/_schema.js @@ -21,7 +21,8 @@ export const organizationsColDefs = (t) => [ valueFormatter: numberFormatter, cellRenderer: LinkRenderer, width: 300, - valueGetter: (params) => params.data.totalBalance, + valueGetter: (params) => + params.data.totalBalance - Math.abs(params.data.reservedBalance), // Temporary measures // filter: 'agNumberColumnFilter', filter: false, diff --git a/frontend/src/views/Transactions/components/OrganizationList.jsx b/frontend/src/views/Transactions/components/OrganizationList.jsx index 1bc750edb..bd9240d79 100644 --- a/frontend/src/views/Transactions/components/OrganizationList.jsx +++ b/frontend/src/views/Transactions/components/OrganizationList.jsx @@ -18,7 +18,9 @@ const OrganizationList = ({ onOrgChange }) => { ...org, label: `${org.name} ${t( 'txn:complianceUnitsBalance' - )}: ${numberFormatter({ value: org.totalBalance })} (${numberFormatter({ + )}: ${numberFormatter({ + value: org.totalBalance - Math.abs(org.reservedBalance) + })} (${numberFormatter({ value: Math.abs(org.reservedBalance) })} ${t('txn:inReserve')})` })) diff --git a/frontend/src/views/Transfers/components/OrganizationBadge.jsx b/frontend/src/views/Transfers/components/OrganizationBadge.jsx index 6ddeaee2a..5f0979be4 100644 --- a/frontend/src/views/Transfers/components/OrganizationBadge.jsx +++ b/frontend/src/views/Transfers/components/OrganizationBadge.jsx @@ -28,8 +28,11 @@ export const OrganizationBadge = ({ {['Submitted', 'Recommended'].includes(transferStatus) && ( - Balance: {orgInfo?.totalBalance.toLocaleString()} ( - {Math.abs(orgInfo?.reservedBalance).toLocaleString()}) + Balance:{' '} + {( + orgInfo?.totalBalance - Math.abs(orgInfo?.reservedBalance) + ).toLocaleString()}{' '} + ({Math.abs(orgInfo?.reservedBalance).toLocaleString()}) Registered: {orgInfo?.registered ? 'Yes' : 'No'} diff --git a/frontend/src/views/Transfers/components/__tests__/OrganizationBadge.test.jsx b/frontend/src/views/Transfers/components/__tests__/OrganizationBadge.test.jsx index a1a18080c..4b2c1a9c9 100644 --- a/frontend/src/views/Transfers/components/__tests__/OrganizationBadge.test.jsx +++ b/frontend/src/views/Transfers/components/__tests__/OrganizationBadge.test.jsx @@ -67,7 +67,7 @@ describe('OrganizationBadge Component', () => { />, { wrapper } ) - expect(screen.getByText('Balance: 1,000 (200)')).toBeInTheDocument() + expect(screen.getByText('Balance: 800 (200)')).toBeInTheDocument() expect(screen.getByText('Registered: Yes')).toBeInTheDocument() }) @@ -103,7 +103,7 @@ describe('OrganizationBadge Component', () => { useOrganizationBalance.mockReturnValue({ data: null, isLoading: true, - isLoadingError: false, + isLoadingError: false }) render( @@ -124,7 +124,7 @@ describe('OrganizationBadge Component', () => { useOrganizationBalance.mockReturnValue({ data: null, isLoading: false, - isLoadingError: true, + isLoadingError: true }) render( @@ -146,10 +146,10 @@ describe('OrganizationBadge Component', () => { data: { totalBalance: 1234567.89, reservedBalance: -123456.78, - registered: false, + registered: false }, isLoading: false, - isLoadingError: false, + isLoadingError: false }) render( @@ -161,7 +161,9 @@ describe('OrganizationBadge Component', () => { />, { wrapper } ) - expect(screen.getByText('Balance: 1,234,567.89 (123,456.78)')).toBeInTheDocument() + expect( + screen.getByText('Balance: 1,111,111.11 (123,456.78)') + ).toBeInTheDocument() expect(screen.getByText('Registered: No')).toBeInTheDocument() }) })