Commit 6aab3d9b authored by tom's avatar tom

Tuple item names are not displayed in the new UI

Fixes #1476
parent 4cd99338
......@@ -14,7 +14,7 @@ export const read: Array<SmartContractReadMethod> = [
method_id: '70a08231',
name: 'FLASHLOAN_PREMIUM_TOTAL',
outputs: [
{ internalType: 'uint256', name: '', type: 'uint256' },
{ internalType: 'uint256', name: 'amount', type: 'uint256' },
],
payable: false,
stateMutability: 'view',
......@@ -97,7 +97,7 @@ export const read: Array<SmartContractReadMethod> = [
export const readResultSuccess: SmartContractQueryMethodReadSuccess = {
is_error: false,
result: {
names: [ 'uint256' ],
names: [ 'amount' ],
output: [
{ type: 'uint256', value: '42' },
],
......
......@@ -97,10 +97,10 @@ export interface SmartContractMethodOutput extends SmartContractMethodInput {
export interface SmartContractQueryMethodReadSuccess {
is_error: false;
result: {
names: Array<string>;
names: Array<string | [ string, Array<string> ]>;
output: Array<{
type: string;
value: string;
value: string | Array<unknown>;
}>;
};
}
......
import { Box, Button, chakra, Flex, Text } from '@chakra-ui/react';
import { Box, Button, chakra, Flex } from '@chakra-ui/react';
import _fromPairs from 'lodash/fromPairs';
import React from 'react';
import type { SubmitHandler } from 'react-hook-form';
......@@ -158,7 +158,17 @@ const ContractMethodCallable = <T extends SmartContractMethod>({ data, onSubmit,
{ 'outputs' in data && !isWrite && data.outputs.length > 0 && (
<Flex mt={ 3 }>
<IconSvg name="arrows/down-right" boxSize={ 5 } mr={ 1 }/>
<Text>{ data.outputs.map(({ type }) => type).join(', ') }</Text>
<p>
{ data.outputs.map(({ type, name }, index) => {
return (
<>
<chakra.span fontWeight={ 500 }>{ name } </chakra.span>
<span>{ name ? `(${ type })` : type }</span>
{ index < data.outputs.length - 1 && <span>, </span> }
</>
);
}) }
</p>
</Flex>
) }
{ result && <ResultComponent item={ data } result={ result } onSettle={ handleTxSettle }/> }
......
......@@ -99,3 +99,34 @@ test('success', async({ mount }) => {
await expect(component).toHaveScreenshot();
});
test('complex success', async({ mount }) => {
const result: ContractMethodReadResult = {
is_error: false,
result: {
names: [
[
'data',
[ 'totalSupply', 'owner', 'symbol' ],
],
'supports721',
'page',
],
output: [
{
type: 'tuple[uint256,address,string]',
value: [ 1000, '0xe150519ae293922cfe6217feba3add4726f5e851', 'AOC_INCUBATORS' ],
},
{ type: 'bool', value: 'true' },
{ type: 'uint256[]', value: [ 1, 2, 3, 4, 5 ] },
],
},
};
const component = await mount(
<TestApp>
<ContractReadResult item={ item } onSettle={ onSettle } result={ result }/>
</TestApp>,
);
await expect(component).toHaveScreenshot();
});
......@@ -2,17 +2,55 @@ import { Alert, Box, chakra, useColorModeValue } from '@chakra-ui/react';
import React from 'react';
import type { ContractMethodReadResult } from './types';
import type { SmartContractReadMethod } from 'types/api/contract';
import type { SmartContractQueryMethodReadSuccess, SmartContractReadMethod } from 'types/api/contract';
import hexToUtf8 from 'lib/hexToUtf8';
const TUPLE_TYPE_REGEX = /\[(.+)\]/;
const ContractReadResultError = ({ children }: {children: React.ReactNode}) => {
return (
<Alert status="error" mt={ 3 } p={ 4 } borderRadius="md" fontSize="sm" wordBreak="break-word" whiteSpace="pre-wrap">
{ children }
</Alert>
);
};
interface ItemProps {
output: SmartContractQueryMethodReadSuccess['result']['output'][0];
name: SmartContractQueryMethodReadSuccess['result']['names'][0];
}
const ContractReadResultItem = ({ output, name }: ItemProps) => {
if (Array.isArray(name)) {
const [ structName, argNames ] = name;
const argTypes = output.type.match(TUPLE_TYPE_REGEX)?.[1].split(',');
return (
<>
<p>
<chakra.span fontWeight={ 500 }> { structName }</chakra.span>
<span> ({ output.type }) :</span>
</p>
{ argNames.map((argName, argIndex) => {
return (
<p key={ argName }>
<chakra.span fontWeight={ 500 }> { argName }</chakra.span>
<span>{ argTypes?.[argIndex] ? ` (${ argTypes[argIndex] })` : '' } : { String(output.value[argIndex]) }</span>
</p>
);
}) }
</>
);
}
return (
<p>
<span> </span>
{ name && <chakra.span fontWeight={ 500 }>{ name } </chakra.span> }
<span>({ output.type }) : { String(output.value) }</span>
</p>
);
};
interface Props {
......@@ -53,14 +91,12 @@ const ContractReadResult = ({ item, result, onSettle }: Props) => {
}
return (
<Box mt={ 3 } p={ 4 } borderRadius="md" bgColor={ resultBgColor } fontSize="sm">
<Box mt={ 3 } p={ 4 } borderRadius="md" bgColor={ resultBgColor } fontSize="sm" whiteSpace="break-spaces" wordBreak="break-all">
<p>
[ <chakra.span fontWeight={ 600 }>{ 'name' in item ? item.name : '' }</chakra.span> method response ]
[ <chakra.span fontWeight={ 500 }>{ 'name' in item ? item.name : '' }</chakra.span> method response ]
</p>
<p>[</p>
{ result.result.output.map(({ type, value }, index) => (
<chakra.p key={ index } whiteSpace="break-spaces" wordBreak="break-all"> { type }: { String(value) }</chakra.p>
)) }
{ result.result.output.map((output, index) => <ContractReadResultItem key={ index } output={ output } name={ result.result.names[index] }/>) }
<p>]</p>
</Box>
);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment