Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ abstract class BaseWalletTransfersFrontendIntegrationTest
offerCard.childElement(className("transfer-offer-sender"))
) should matchText(expectedAns(aliceUserParty, aliceAnsName))

seleniumText(
offerCard.childElement(className("transfer-offer-received"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

transfer-offer-receiver

) should matchText(expectedAns(bobUserParty, bobAnsName))

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this pass? You shouldn't see both the sender and receiver at the same time according to the rendering logic below

offerCard
.childElement(className("transfer-offer-amulet-amount"))
.text should matchText(
Expand All @@ -143,6 +147,7 @@ abstract class BaseWalletTransfersFrontendIntegrationTest
val aliceDamlUser = aliceWalletClient.config.ledgerApiUser
val aliceUserParty = onboardWalletUser(aliceWalletClient, aliceValidatorBackend)
val aliceAnsName = perTestCaseName("alice")
val aliceAnsDisplay = expectedAns(aliceUserParty, aliceAnsName)

val bobUserParty = onboardWalletUser(bobWalletClient, bobValidatorBackend)
val bobAnsName = perTestCaseName("bob")
Expand Down Expand Up @@ -190,6 +195,10 @@ abstract class BaseWalletTransfersFrontendIntegrationTest
offerCard.childElement(className("transfer-offer-sender"))
) should matchText(bobAnsDisplay)

seleniumText(
offerCard.childElement(className("transfer-offer-received"))
) should matchText(aliceAnsDisplay)

offerCard.childElement(className("transfer-offer-expiry")).text should matchText(
s"Expires $expectedExpiry"
)
Expand Down
2 changes: 2 additions & 0 deletions apps/wallet/frontend/src/components/SendTransfer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import useLookupTransferPreapproval from '../hooks/scan-proxy/useLookupTransferP
import BftAnsField from './BftAnsField';
import { useFeatureSupport } from '../hooks/useFeatureSupport';
import AmountInput from './AmountInput';
import { TransferOffers } from './TransferOffers';

const SendTransfer: React.FC = () => {
const { createTransferOffer, transferPreapprovalSend, createTransferViaTokenStandard } =
Expand Down Expand Up @@ -252,6 +253,7 @@ const SendTransfer: React.FC = () => {
</DisableConditionally>
</CardContent>
</Card>
<TransferOffers mode="received" />
</Stack>
);
};
Expand Down
85 changes: 58 additions & 27 deletions apps/wallet/frontend/src/components/TransferOffers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,14 @@ type PartialWalletTransferOffer = {
sender: string;
expiresAt: string;
isTokenStandard: boolean;
receiver: string;
};
export const TransferOffers: React.FC = () => {

type TransferOffersListProps = {
mode: 'sent' | 'received';
};

export const TransferOffers: React.FC<TransferOffersListProps> = ({ mode }) => {
const [offers, setOffers] = useState<WalletTransferOffer[]>([]);
const amuletPriceQuery = useAmuletPrice();
const primaryPartyId = usePrimaryParty();
Expand All @@ -46,7 +52,9 @@ export const TransferOffers: React.FC = () => {
amuletPrice: BigNumber
): Promise<WalletTransferOffer[]> => {
return items
.filter(item => item.sender !== primaryPartyId)
.filter(item =>
mode === 'received' ? item.sender === primaryPartyId : item.sender !== primaryPartyId
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should flip this, see my comment below about the modes.

)
.map(item => {
return {
contractId: item.contractId,
Expand All @@ -59,12 +67,13 @@ export const TransferOffers: React.FC = () => {
amuletPrice
),
senderId: item.sender,
receiverId: item.receiver,
expiry: item.expiresAt,
isTokenStandard: item.isTokenStandard,
};
});
},
[primaryPartyId]
[primaryPartyId, mode]
);

const transferOfferContractsQuery = useTransferOffers(amuletPriceQuery.data);
Expand All @@ -82,6 +91,7 @@ export const TransferOffers: React.FC = () => {
contractId: offer.contractId,
amount: offer.payload.amount.amount,
sender: offer.payload.sender,
receiver: offer.payload.receiver,
expiresAt: offer.payload.expiresAt,
};
return item;
Expand All @@ -93,6 +103,7 @@ export const TransferOffers: React.FC = () => {
contractId: transfer.contractId,
amount: transfer.payload.transfer.amount,
sender: transfer.payload.transfer.sender,
receiver: transfer.payload.transfer.receiver,
expiresAt: transfer.payload.transfer.executeBefore,
};
return item;
Expand All @@ -110,11 +121,12 @@ export const TransferOffers: React.FC = () => {
amuletPriceQuery.isError ||
transferOfferContractsQuery.isError ||
tokenStandardTransfersQuery.isError;
const heading = mode === 'received' ? 'Pending Offers ' : 'Action Needed ';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should flip this, see my comment below about the modes.


return (
<Stack spacing={4} direction="column" justifyContent="center" id="transfer-offers">
<Typography mt={6} variant="h4">
Action Needed{' '}
{heading}
<Chip label={offers.length} color="success" className="transfer-offers-count" />
</Typography>
{isLoading ? (
Expand All @@ -127,7 +139,7 @@ export const TransferOffers: React.FC = () => {
</Box>
) : (
offers.map((offer, index) => (
<TransferOfferDisplay key={'offer-' + index} transferOffer={offer} />
<TransferOfferDisplay key={'offer-' + index} transferOffer={offer} mode={mode} />
))
)}
</Stack>
Expand All @@ -136,11 +148,14 @@ export const TransferOffers: React.FC = () => {

interface TransferOfferProps {
transferOffer: WalletTransferOffer;
mode: 'sent' | 'received';
}

export const TransferOfferDisplay: React.FC<TransferOfferProps> = props => {
const config = useWalletConfig();
const offer = props.transferOffer;
const mode = props.mode;

const {
acceptTransferOffer,
rejectTransferOffer,
Expand All @@ -163,11 +178,19 @@ export const TransferOfferDisplay: React.FC<TransferOfferProps> = props => {
<ArrowCircleLeftOutlined fontSize="large" />
<Stack direction="row" alignItems="center">
<Stack direction="column">
<BftAnsEntry
partyId={offer.senderId}
variant="h5"
className={'transfer-offer-sender'}
/>
{mode === 'sent' ? (
<BftAnsEntry
partyId={offer.senderId}
variant="h5"
className={'transfer-offer-sender'}
/>
) : (
<BftAnsEntry
partyId={offer.receiverId}
variant="h5"
className={'transfer-offer-received'}
/>
)}
</Stack>
</Stack>
<Stack direction="column" alignItems="flex-end">
Expand All @@ -186,23 +209,31 @@ export const TransferOfferDisplay: React.FC<TransferOfferProps> = props => {
</Typography>
</Stack>
<Stack direction="row" alignItems="center" spacing={2}>
<Button
variant="pill"
size="small"
onClick={() => accept(offer.contractId)}
className="transfer-offer-accept"
>
Accept
</Button>
<Button
variant="pill"
color="warning"
size="small"
onClick={() => reject(offer.contractId)}
className="transfer-offer-reject"
>
Reject
</Button>
{mode === 'sent' ? (
<>
<Button
variant="pill"
size="small"
onClick={() => accept(offer.contractId)}
className="transfer-offer-accept"
>
Accept
</Button>
<Button
variant="pill"
color="warning"
size="small"
onClick={() => reject(offer.contractId)}
className="transfer-offer-reject"
>
Reject
</Button>
</>
) : (
<Typography variant="pill" className="pending-offer">
Pending acceptance
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need this as it's constant across all items in this list. The title of the section already indicates that each item in the list is pending acknowledgement(acceptance/rejection).

</Typography>
)}
</Stack>
<Typography variant="caption" className="transfer-offer-expiry">
Expires <DateDisplay datetime={offer.expiry} />
Expand Down
1 change: 1 addition & 0 deletions apps/wallet/frontend/src/models/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ export interface WalletTransferOffer {
conversionRate: string;
convertedCurrency: ConvertedCurrency;
senderId: string;
receiverId: string;
expiry: string;
isTokenStandard: boolean;
}
Expand Down
2 changes: 1 addition & 1 deletion apps/wallet/frontend/src/routes/transactions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const Transactions: React.FC = () => {
<DevNetOnly>
<Tap />
</DevNetOnly>
<TransferOffers />
<TransferOffers mode="sent" />
<TransactionHistory />
</Box>
);
Expand Down