UX improvement
-- Related smart contract transactions will be grouped together
This commit is contained in:
parent
11c66d550d
commit
ac3f06a341
33
css/main.css
33
css/main.css
@ -1020,6 +1020,7 @@ theme-toggle {
|
|||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 1.5rem;
|
gap: 1.5rem;
|
||||||
|
min-width: 0;
|
||||||
}
|
}
|
||||||
.transaction > .icon:first-of-type {
|
.transaction > .icon:first-of-type {
|
||||||
fill: none;
|
fill: none;
|
||||||
@ -1046,6 +1047,25 @@ theme-toggle {
|
|||||||
color: rgba(var(--text-color), 0.8);
|
color: rgba(var(--text-color), 0.8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.transfer-steps {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.transfer-step {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem 2rem;
|
||||||
|
border: solid thin rgba(var(--text-color), 0.4);
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
}
|
||||||
|
.transfer-step > :nth-child(2) {
|
||||||
|
width: auto;
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
|
||||||
#loading {
|
#loading {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
display: grid;
|
display: grid;
|
||||||
@ -1263,6 +1283,19 @@ theme-toggle {
|
|||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
margin-top: 0.2rem !important;
|
margin-top: 0.2rem !important;
|
||||||
}
|
}
|
||||||
|
.transfer-step {
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
.transfer-step > :nth-child(1) {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
.transfer-step > :nth-child(2) {
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
.transfer-step > :nth-child(3) {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@media only screen and (min-width: 1280px) {
|
@media only screen and (min-width: 1280px) {
|
||||||
.margin,
|
.margin,
|
||||||
|
|||||||
2
css/main.min.css
vendored
2
css/main.min.css
vendored
File diff suppressed because one or more lines are too long
@ -930,6 +930,7 @@ theme-toggle {
|
|||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 1.5rem;
|
gap: 1.5rem;
|
||||||
|
min-width: 0;
|
||||||
}
|
}
|
||||||
& > .icon:first-of-type {
|
& > .icon:first-of-type {
|
||||||
fill: none;
|
fill: none;
|
||||||
@ -955,6 +956,23 @@ theme-toggle {
|
|||||||
background-color: rgba(var(--text-color), 0.1);
|
background-color: rgba(var(--text-color), 0.1);
|
||||||
color: rgba(var(--text-color), 0.8);
|
color: rgba(var(--text-color), 0.8);
|
||||||
}
|
}
|
||||||
|
.transfer-steps {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
.transfer-step {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem 2rem;
|
||||||
|
border: solid thin rgba(var(--text-color), 0.4);
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
> :nth-child(2) {
|
||||||
|
width: auto;
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
#loading {
|
#loading {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
display: grid;
|
display: grid;
|
||||||
@ -1165,6 +1183,19 @@ theme-toggle {
|
|||||||
margin-top: 0.2rem !important;
|
margin-top: 0.2rem !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.transfer-step {
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: row;
|
||||||
|
> :nth-child(1) {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
> :nth-child(2) {
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
> :nth-child(3) {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@media only screen and (min-width: 1280px) {
|
@media only screen and (min-width: 1280px) {
|
||||||
.margin,
|
.margin,
|
||||||
|
|||||||
117
index.html
117
index.html
@ -810,10 +810,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="contract-info">
|
<div class="contract-info">
|
||||||
<time>${getFormattedTime(time)}</time>
|
<time>${getFormattedTime(time)}</time>
|
||||||
<div class="flex flex-direction-column">
|
|
||||||
<h5 class="label">Contract name</h5>
|
|
||||||
<h4>${contractName}</h4>
|
|
||||||
</div>
|
|
||||||
<div class="flex flex-direction-column">
|
<div class="flex flex-direction-column">
|
||||||
<h5 class="label">contract address</h5>
|
<h5 class="label">contract address</h5>
|
||||||
<a href=${`#/address/${contractAddress}`} class="address wrap-around">${contractAddress}</a>
|
<a href=${`#/address/${contractAddress}`} class="address wrap-around">${contractAddress}</a>
|
||||||
@ -947,10 +943,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="contract-info">
|
<div class="contract-info">
|
||||||
<time>${getFormattedTime(time)}</time>
|
<time>${getFormattedTime(time)}</time>
|
||||||
<div class="flex flex-direction-column">
|
|
||||||
<h5 class="label">Contract name</h5>
|
|
||||||
<h4>${contractName}</h4>
|
|
||||||
</div>
|
|
||||||
<div class="flex flex-direction-column">
|
<div class="flex flex-direction-column">
|
||||||
<h5 class="label">Sender (Smart contract)</h5>
|
<h5 class="label">Sender (Smart contract)</h5>
|
||||||
<a href=${`#/contract/${contractName}-${senderAddress}`} class="address wrap-around">${contractName}-${senderAddress}</a>
|
<a href=${`#/contract/${contractName}-${senderAddress}`} class="address wrap-around">${contractName}-${senderAddress}</a>
|
||||||
@ -976,6 +968,61 @@
|
|||||||
`: ''}
|
`: ''}
|
||||||
</div>
|
</div>
|
||||||
</li>`;
|
</li>`;
|
||||||
|
},
|
||||||
|
compoundTransactionCard(details) {
|
||||||
|
const { time, hash, sender, receiver, contractName, token, amount, offChainTransactions = [] } = details
|
||||||
|
const smartContract = `${contractName}-${receiver}`
|
||||||
|
const renderedOffChainTransactions = offChainTransactions.map(tx => {
|
||||||
|
const { receiverAddress, tokenAmount, tokenIdentification } = tx
|
||||||
|
return html`
|
||||||
|
<li class="transfer-step">
|
||||||
|
<div class="flex flex-direction-column gap-0-5">
|
||||||
|
<div class="flex flex-direction-column">
|
||||||
|
<h5 class="label">Sender (Smart contract)</h5>
|
||||||
|
<a href=${`#/contract/${smartContract}`} class="address wrap-around">${smartContract}</a>
|
||||||
|
</div>
|
||||||
|
<p>Sent: <b>${tokenAmount} ${tokenIdentification}</b></p>
|
||||||
|
</div>
|
||||||
|
<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M12 4l-1.41 1.41L16.17 11H4v2h12.17l-5.58 5.59L12 20l8-8-8-8z"/></svg>
|
||||||
|
<div class="flex flex-direction-column">
|
||||||
|
<h5 class="label">Receiver</h5>
|
||||||
|
<sm-copy value=${receiverAddress}>
|
||||||
|
<a href=${`#/address/${receiverAddress}`} class="address wrap-around">${receiverAddress}</a>
|
||||||
|
</sm-copy>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
`
|
||||||
|
})
|
||||||
|
return html`
|
||||||
|
<li class="transaction">
|
||||||
|
<svg class="icon" viewBox="0 0 64 64"> <title>transfer</title> <polyline points="17.04 35.97 14.57 33.5 40.15 7.9 32.75 0.5 55.52 0.5 55.52 23.28 48.12 15.87 23.86 40.14 15.88 48.13 8.48 40.72 8.48 63.5 31.25 63.5 23.85 56.1 49.43 30.5 46.96 28.03"/> </svg>
|
||||||
|
<div class="contract-type flex flex-direction-column gap-0-5">
|
||||||
|
<h4>Smart contract transfer</h4>
|
||||||
|
<time>${getFormattedTime(time)}</time>
|
||||||
|
</div>
|
||||||
|
<div class="contract-info">
|
||||||
|
<ul class="transfer-steps">
|
||||||
|
<li class="transfer-step">
|
||||||
|
<div class="flex flex-direction-column gap-0-5">
|
||||||
|
<div class="flex flex-direction-column">
|
||||||
|
<h5 class="label">Sender</h5>
|
||||||
|
<sm-copy value=${sender}>
|
||||||
|
<a href=${`#/address/${sender}`} class="address wrap-around">${sender}</a>
|
||||||
|
</sm-copy>
|
||||||
|
<p>Sent: <b>${amount} ${token}</b></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M12 4l-1.41 1.41L16.17 11H4v2h12.17l-5.58 5.59L12 20l8-8-8-8z"/></svg>
|
||||||
|
<div class="flex flex-direction-column">
|
||||||
|
<h5 class="label">Receiver (Smart contract)</h5>
|
||||||
|
<a href=${`#/contract/${smartContract}`} class="address wrap-around">${smartContract}</a>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
${renderedOffChainTransactions}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
`
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const router = new Router({
|
const router = new Router({
|
||||||
@ -1498,32 +1545,68 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function renderTransactions(transactions = []) {
|
function renderTransactions(transactions = []) {
|
||||||
let txFrag = parseTransactions(transactions);
|
let parsedTxs = parseTransactions(transactions);
|
||||||
const renderedTransactions = txFrag.map(tx => {
|
let groupedTxs = new Map();
|
||||||
|
|
||||||
|
parsedTxs.forEach((tx) => {
|
||||||
|
const { hash, transactionTrigger } = tx;
|
||||||
|
const key = hash || transactionTrigger;
|
||||||
|
|
||||||
|
if (!groupedTxs.has(key)) {
|
||||||
|
groupedTxs.set(key, {
|
||||||
|
sourceTransaction: null,
|
||||||
|
offChainTransactions: [],
|
||||||
|
type: transactionTrigger ? 'compoundTransaction' : undefined,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hash) {
|
||||||
|
groupedTxs.get(key).sourceTransaction = tx;
|
||||||
|
} else {
|
||||||
|
const { tokenIdentification, senderAddress, receiverAddress, onChain, tokenAmount } = tx;
|
||||||
|
groupedTxs.get(key).offChainTransactions.push({
|
||||||
|
tokenIdentification,
|
||||||
|
receiverAddress,
|
||||||
|
tokenAmount,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Convert the Map to an array of values for sorting
|
||||||
|
const sortedTxs = [...groupedTxs.values()].sort((a, b) => b.sourceTransaction.time - a.sourceTransaction.time);
|
||||||
|
|
||||||
|
// Replace parsedTxs with sortedTxs
|
||||||
|
parsedTxs = sortedTxs.map((tx) => {
|
||||||
|
if (tx.type === 'compoundTransaction') {
|
||||||
|
return {
|
||||||
|
...tx.sourceTransaction,
|
||||||
|
offChainTransactions: tx.offChainTransactions,
|
||||||
|
type: tx.type,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return tx.sourceTransaction;
|
||||||
|
});
|
||||||
|
console.log(parsedTxs)
|
||||||
|
const renderedTransactions = parsedTxs.map(tx => {
|
||||||
switch (tx.type) {
|
switch (tx.type) {
|
||||||
case 'tokentransfer':
|
case 'tokentransfer':
|
||||||
case 'nfttransfer':
|
case 'nfttransfer':
|
||||||
return render.tokenTransferCard(tx)
|
return render.tokenTransferCard(tx)
|
||||||
break;
|
|
||||||
case 'contractdeposit':
|
case 'contractdeposit':
|
||||||
return render.contractDepositCard(tx)
|
return render.contractDepositCard(tx)
|
||||||
break;
|
|
||||||
case 'contracttransfer':
|
case 'contracttransfer':
|
||||||
return render.contractTransferCard(tx);
|
return render.contractTransferCard(tx);
|
||||||
break;
|
|
||||||
case 'tokenincorp':
|
case 'tokenincorp':
|
||||||
case 'nftincorp':
|
case 'nftincorp':
|
||||||
return render.tokenCreationCard(tx);
|
return render.tokenCreationCard(tx);
|
||||||
break;
|
|
||||||
case 'contractincorp':
|
case 'contractincorp':
|
||||||
return render.contractCreationCard(tx);
|
return render.contractCreationCard(tx);
|
||||||
break;
|
|
||||||
case 'contracttrigger':
|
case 'contracttrigger':
|
||||||
return render.contractTriggerCard(tx);
|
return render.contractTriggerCard(tx);
|
||||||
break;
|
|
||||||
case 'offChainTransfer':
|
case 'offChainTransfer':
|
||||||
return render.offChainTransferCard(tx);
|
return render.offChainTransferCard(tx);
|
||||||
break;
|
case 'compoundTransaction':
|
||||||
|
return render.compoundTransactionCard(tx)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return html`${renderedTransactions.length ? renderedTransactions : html`<div class="no-results">No transactions found</div>`}`
|
return html`${renderedTransactions.length ? renderedTransactions : html`<div class="no-results">No transactions found</div>`}`
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user