make parsed calldata adaptive

Signed-off-by: Uncle Fatso <uncle.fatso@ghostchain.io>
This commit is contained in:
Uncle Fatso 2026-03-02 14:03:36 +03:00
parent 98a6a5b5d2
commit 670e85889b
Signed by: f4ts0
GPG Key ID: 565F4F2860226EBB
7 changed files with 172 additions and 79 deletions

View File

@ -1,7 +1,7 @@
{ {
"name": "ghost-dao-interface", "name": "ghost-dao-interface",
"private": true, "private": true,
"version": "0.5.33", "version": "0.5.34",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",

View File

@ -200,21 +200,41 @@ const NewProposal = ({ config, address, connect, chainId }) => {
</Box> </Box>
} }
> >
<TableContainer> {isSmallScreen
<Table aria-label="Available bonds" style={{ tableLayout: "fixed" }}> ? <Box display="flex" flexDirection="column">
<TableHead> {proposalFunctions?.map((metadata, index) => {
<TableRow> return parseFunctionCalldata({
<TableCell align="center" style={{ padding: "8px 0" }}>Function</TableCell> metadata,
<TableCell align="center" style={{ padding: "8px 0" }}>Target</TableCell> index,
<TableCell align="center" style={{ padding: "8px 0" }}>Calldata</TableCell> chainId,
<TableCell align="center" style={{ padding: "8px 0" }}>Value</TableCell> removeCalldata,
</TableRow> nativeCoin: nativeCurrency,
</TableHead> isTable: false,
<TableBody>{proposalFunctions.map((metadata, index) => { });
return parseFunctionCalldata(metadata, index, chainId, nativeCurrency, removeCalldata); })}
})}</TableBody> </Box>
</Table> : <TableContainer>
</TableContainer> <Table aria-label="Available bonds" style={{ tableLayout: "fixed" }}>
<TableHead>
<TableRow>
<TableCell align="center" style={{ padding: "8px 0" }}>Function</TableCell>
<TableCell align="center" style={{ padding: "8px 0" }}>Target</TableCell>
<TableCell align="center" style={{ padding: "8px 0" }}>Calldata</TableCell>
<TableCell align="center" style={{ padding: "8px 0" }}>Value</TableCell>
</TableRow>
</TableHead>
<TableBody>{proposalFunctions?.map((metadata, index) => {
return parseFunctionCalldata({
metadata,
index,
chainId,
removeCalldata,
nativeCoin: nativeCurrency,
});
})}</TableBody>
</Table>
</TableContainer>
}
</Paper>} </Paper>}
</Box> </Box>
</Container> </Container>

View File

@ -216,15 +216,20 @@ const ProposalDetails = ({ chainId, address, connect, config }) => {
}} }}
> >
<Box sx={{ mt: "15px" }}> <Box sx={{ mt: "15px" }}>
<Box display="flex" justifyContent="space-between" gap="20px"> <Box
gap="20px"
display="flex"
justifyContent={"space-between"}
flexDirection={isSmallScreen ? "column" : "row"}
>
<Paper <Paper
fullWidth fullWidth
enableBackground enableBackground
headerContent={ headerContent={
<Box display="flex" alignItems="center" flexDirection="row" gap="10px"> <Box display="flex" alignItems="center" flexDirection="row" gap="10px">
<Typography variant="h6"> {!isSmallScreen &&<Typography variant="h6">
Progress Progress
</Typography> </Typography>}
<Chip <Chip
sx={{ marginTop: "4px", width: "88px" }} sx={{ marginTop: "4px", width: "88px" }}
label={convertStatusToLabel(proposalState)} label={convertStatusToLabel(proposalState)}
@ -306,14 +311,14 @@ const ProposalDetails = ({ chainId, address, connect, config }) => {
disabled={proposalState !== 1 || pastVotes?._value === 0n || isPending} disabled={proposalState !== 1 || pastVotes?._value === 0n || isPending}
onClick={() => handleVote(1)} onClick={() => handleVote(1)}
> >
For {isPending ? "Voting..." : "For"}
</SecondaryButton> </SecondaryButton>
<SecondaryButton <SecondaryButton
fullWidth fullWidth
disabled={proposalState !== 1 || pastVotes?._value === 0n || isPending} disabled={proposalState !== 1 || pastVotes?._value === 0n || isPending}
onClick={() => handleVote(0)} onClick={() => handleVote(0)}
> >
Against {isPending ? "Voting..." : "Against"}
</SecondaryButton> </SecondaryButton>
</> </>
: <SecondaryButton : <SecondaryButton
@ -365,21 +370,39 @@ const ProposalDetails = ({ chainId, address, connect, config }) => {
</Box> </Box>
} }
> >
<TableContainer> {isSmallScreen
<Table aria-label="Available bonds" style={{ tableLayout: "fixed" }}> ? <Box display="flex" flexDirection="column">
<TableHead> {proposalDetails?.map((metadata, index) => {
<TableRow> return parseFunctionCalldata({
<TableCell align="center" style={{ padding: "8px 0" }}>Function</TableCell> metadata,
<TableCell align="center" style={{ padding: "8px 0" }}>Target</TableCell> index,
<TableCell align="center" style={{ padding: "8px 0" }}>Calldata</TableCell> chainId,
<TableCell align="center" style={{ padding: "8px 0" }}>Value</TableCell> nativeCoin: nativeCurrency,
</TableRow> isTable: false,
</TableHead> });
<TableBody>{proposalDetails?.map((metadata, index) => { })}
return parseFunctionCalldata(metadata, index, chainId, nativeCurrency); </Box>
})}</TableBody> : <TableContainer>
</Table> <Table aria-label="Available bonds" style={{ tableLayout: "fixed" }}>
</TableContainer> <TableHead>
<TableRow>
<TableCell align="center" style={{ padding: "8px 0" }}>Function</TableCell>
<TableCell align="center" style={{ padding: "8px 0" }}>Target</TableCell>
<TableCell align="center" style={{ padding: "8px 0" }}>Calldata</TableCell>
<TableCell align="center" style={{ padding: "8px 0" }}>Value</TableCell>
</TableRow>
</TableHead>
<TableBody>{proposalDetails?.map((metadata, index) => {
return parseFunctionCalldata({
metadata,
index,
chainId,
nativeCoin: nativeCurrency,
});
})}</TableBody>
</Table>
</TableContainer>
}
</Paper> </Paper>
</Container> </Container>
</Box> </Box>
@ -418,7 +441,12 @@ const VotingTimeline = ({ connect, handleExecute, handleRelease, proposalLocked,
disabled={isPending || state !== 4} disabled={isPending || state !== 4}
onClick={() => address === "" ? connect() : handleExecute()} onClick={() => address === "" ? connect() : handleExecute()}
> >
{address === "" ? "Connect" : state === 4 ? "Execute" : convertStatusToLabel(state)} {address === ""
? "Connect"
: state !== 4
? convertStatusToLabel(state)
: isPending ? "Executing..." : "Execute"
}
</SecondaryButton> </SecondaryButton>
</Box> </Box>
</Box> </Box>

View File

@ -27,13 +27,5 @@ export const AuditReservesSteps = () => {
} }
export const AuditReservesParsed = (props) => { export const AuditReservesParsed = (props) => {
return (
<>
{props.isTable && <AuditReservesParsedCell {...props} />}
</>
)
}
const AuditReservesParsedCell = (props) => {
return <ParsedCell {...props} /> return <ParsedCell {...props} />
} }

View File

@ -34,6 +34,7 @@ export const prepareCreateBondDescription = "function creates a new bond market
export const CreateBondParsed = (props) => { export const CreateBondParsed = (props) => {
const [isOpened, setIsOpened] = useState(false); const [isOpened, setIsOpened] = useState(false);
const { symbol: ftsoSymbol } = useTokenSymbol(props.chainId, "FTSO"); const { symbol: ftsoSymbol } = useTokenSymbol(props.chainId, "FTSO");
console.log(props)
return ( return (
<> <>
<Modal <Modal
@ -51,15 +52,11 @@ export const CreateBondParsed = (props) => {
<CreateBondSteps args={props.args} ftsoSymbol={ftsoSymbol} nativeCurrency={props.nativeCoin} {...props} /> <CreateBondSteps args={props.args} ftsoSymbol={ftsoSymbol} nativeCurrency={props.nativeCoin} {...props} />
</Box> </Box>
</Modal> </Modal>
{props.isTable && <CreateBondParsedCell isOpened={isOpened} setIsOpened={setIsOpened} {...props}/>} <ParsedCell isOpened={isOpened} setIsOpened={setIsOpened} {...props} />
</> </>
) )
} }
const CreateBondParsedCell = (props) => {
return <ParsedCell {...props} />
}
export const CreateBondSteps = ({ nativeCurrency, ftsoSymbol, chainId, toInitialStep, addCalldata, args }) => { export const CreateBondSteps = ({ nativeCurrency, ftsoSymbol, chainId, toInitialStep, addCalldata, args }) => {
const createMode = args === undefined; const createMode = args === undefined;

View File

@ -45,15 +45,11 @@ export const SetAdjustmentParsed = (props) => {
<SetAdjustmentSteps {...props} /> <SetAdjustmentSteps {...props} />
</Box> </Box>
</Modal> </Modal>
{props.isTable && <SetAdjustmentParsedCell isOpened={isOpened} setIsOpened={setIsOpened} {...props} />} <ParsedCell isOpened={isOpened} setIsOpened={setIsOpened} {...props} />
</> </>
) )
} }
const SetAdjustmentParsedCell = (props) => {
return <ParsedCell {...props} />
}
export const SetAdjustmentSteps = ({ chainId, toInitialStep, addCalldata, args }) => { export const SetAdjustmentSteps = ({ chainId, toInitialStep, addCalldata, args }) => {
const createMode = args === undefined; const createMode = args === undefined;

View File

@ -44,7 +44,14 @@ const identifyAction = (calldata) => {
return decoded; return decoded;
} }
export const parseFunctionCalldata = (metadata, index, chainId, nativeCoin, removeCalldata) => { export const parseFunctionCalldata = ({
metadata,
index,
chainId,
nativeCoin,
removeCalldata,
isTable = true,
}) => {
const { label, calldata, target, value } = metadata; const { label, calldata, target, value } = metadata;
const { functionName, args } = identifyAction(calldata); const { functionName, args } = identifyAction(calldata);
const labelOrName = label ?? (functionName ?? "Unknown"); const labelOrName = label ?? (functionName ?? "Unknown");
@ -54,7 +61,7 @@ export const parseFunctionCalldata = (metadata, index, chainId, nativeCoin, remo
switch (functionName) { switch (functionName) {
case "auditReserves": case "auditReserves":
return <AuditReservesParsed return <AuditReservesParsed
isTable isTable={isTable}
key={index} key={index}
calldata={calldata} calldata={calldata}
label={labelOrName} label={labelOrName}
@ -67,7 +74,7 @@ export const parseFunctionCalldata = (metadata, index, chainId, nativeCoin, remo
/>; />;
case "setAdjustment": case "setAdjustment":
return <SetAdjustmentParsed return <SetAdjustmentParsed
isTable isTable={isTable}
args={args} args={args}
key={index} key={index}
calldata={calldata} calldata={calldata}
@ -81,7 +88,7 @@ export const parseFunctionCalldata = (metadata, index, chainId, nativeCoin, remo
/>; />;
case "create": case "create":
return <CreateBondParsed return <CreateBondParsed
isTable isTable={isTable}
args={args} args={args}
key={index} key={index}
calldata={calldata} calldata={calldata}
@ -95,7 +102,7 @@ export const parseFunctionCalldata = (metadata, index, chainId, nativeCoin, remo
/>; />;
default: default:
return <ParsedCell return <ParsedCell
isTable isTable={isTable}
key={index} key={index}
calldata={calldata} calldata={calldata}
label="Unknown" label="Unknown"
@ -250,6 +257,7 @@ export const ArgumentInput = ({
) )
} }
// TODO: rename
export const ParsedCell = (props) => { export const ParsedCell = (props) => {
const [isCopied, setIsCopied] = useState(false); const [isCopied, setIsCopied] = useState(false);
@ -275,34 +283,86 @@ export const ParsedCell = (props) => {
} }
}; };
return ( if (props.isTable) {
<TableRow id={props.id + `--proposalFunction`} data-testid={props.id + `--proposalFunction`}> return (
<TableCell align="center" style={{ padding: "8px 0" }}> <TableRow id={props.id + `--proposalFunction`} data-testid={props.id + `--proposalFunction`}>
<Typography>{props.label}</Typography> <TableCell align="center" style={{ padding: "8px 0" }}>
</TableCell> <Typography>{props.label}</Typography>
</TableCell>
<TableCell align="center" style={{ padding: "8px 0" }}> <TableCell align="center" style={{ padding: "8px 0" }}>
<Link href={etherscanLink} target="_blank" rel="noopener noreferrer">
<Typography>{shorten(props.target)}</Typography>
</Link>
</TableCell>
<TableCell align="center" style={{ padding: "8px 0" }}>
<Link onClick={handleCalldataCopy} target="_blank" rel="noopener noreferrer">
<Typography>{shorten(props.calldata)}</Typography>
</Link>
</TableCell>
<TableCell align="center" style={{ padding: "8px 0" }}>
<Typography>{formatCurrency(props.value, 4, props.nativeCoin)}</Typography>
</TableCell>
<TableCell>
<div style={{ display: 'flex', gap: '8px' }}>
{props.args && <TertiaryButton fullWidth onClick={() => props.setIsOpened(!props.isOpened)}>View</TertiaryButton>}
{props.remove && <TertiaryButton fullWidth onClick={() => props.remove()}>Delete</TertiaryButton>}
</div>
</TableCell>
</TableRow>
)
}
return (
<Box
id={props.id + `--proposalFunction`}
data-testid={props.id + `--proposalFunction`}
display="flex"
flexDirection="column"
>
<Box display="flex" justifyContent="space-between">
<Typography>{`Function ${props.id + 1}`}</Typography>
<Typography>{props.label}</Typography>
</Box>
<Box display="flex" justifyContent="space-between">
<Typography>Target</Typography>
<Link href={etherscanLink} target="_blank" rel="noopener noreferrer"> <Link href={etherscanLink} target="_blank" rel="noopener noreferrer">
<Typography>{shorten(props.target)}</Typography> <Typography>{shorten(props.target)}</Typography>
</Link> </Link>
</TableCell> </Box>
<TableCell align="center" style={{ padding: "8px 0" }}> <Box display="flex" justifyContent="space-between">
<Typography>Calldata</Typography>
<Link onClick={handleCalldataCopy} target="_blank" rel="noopener noreferrer"> <Link onClick={handleCalldataCopy} target="_blank" rel="noopener noreferrer">
<Typography>{shorten(props.calldata)}</Typography> <Typography>{shorten(props.calldata)}</Typography>
</Link> </Link>
</TableCell> </Box>
<TableCell align="center" style={{ padding: "8px 0" }}> <Box display="flex" justifyContent="space-between">
<Typography>{formatCurrency(props.value, 4, props.nativeCoin)}</Typography> <Typography>Value</Typography>
</TableCell> <Link onClick={handleCalldataCopy} target="_blank" rel="noopener noreferrer">
<Typography>{formatCurrency(props.value, 4, props.nativeCoin)}</Typography>
</Link>
</Box>
<TableCell> {(props.args || props.remove) && <Box
<div style={{ display: 'flex', gap: '8px' }}> display="flex"
{props.args && <TertiaryButton fullWidth onClick={() => props.setIsOpened(!props.isOpened)}>View</TertiaryButton>} flexDirection="row"
{props.remove && <TertiaryButton fullWidth onClick={() => props.remove()}>Delete</TertiaryButton>} justifyContent="space-between"
</div> gap="10px"
</TableCell> marginTop="10px"
</TableRow> >
{props.args && <TertiaryButton fullWidth onClick={() => props.setIsOpened(!props.isOpened)}>View</TertiaryButton>}
{props.remove && <TertiaryButton fullWidth onClick={() => props.remove()}>Delete</TertiaryButton>}
</Box>}
<hr width="100%" style={{ margin: "20px 0" }} />
</Box>
) )
} }