-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rewrite code to implement new ProposalActionsDecoder component
- Loading branch information
Showing
35 changed files
with
395 additions
and
552 deletions.
There are no files selected for viewing
2 changes: 2 additions & 0 deletions
2
src/modules/components/proposal/proposalActions/proposalActionsDecoder/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export { ProposalActionsDecoder } from './proposalActionsDecoder'; | ||
export { ProposalActionsDecoderView, type IProposalActionsDecoderProps } from './proposalActionsDecoder.api'; |
39 changes: 39 additions & 0 deletions
39
.../components/proposal/proposalActions/proposalActionsDecoder/proposalActionsDecoder.api.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import { type ComponentProps } from 'react'; | ||
import type { IProposalAction } from '../proposalActionsDefinitions'; | ||
|
||
export enum ProposalActionsDecoderView { | ||
DECODED = 'DECODED', | ||
RAW = 'RAW', | ||
} | ||
|
||
export enum ProposalActionsDecoderMode { | ||
READ = 'READ', | ||
EDIT = 'EDIT', | ||
WATCH = 'WATCH', | ||
} | ||
|
||
export interface IProposalActionsDecoderProps extends ComponentProps<'div'> { | ||
/** | ||
* Action to display the values for. | ||
*/ | ||
action: IProposalAction; | ||
/** | ||
* Prefix to be appended to all the action values on edit mode. | ||
*/ | ||
formPrefix?: string; | ||
/** | ||
* Defines the behaviour of the decoder: | ||
* - READ: Displays the values as disabled using the values on the action property; | ||
* - EDIT: Displays the values as editable and updates the values on the form context; | ||
* - WATCH: Displays the values as disabled but each value listens to the changes on the form context | ||
* @default READ | ||
*/ | ||
mode?: ProposalActionsDecoderMode; | ||
/** | ||
* Defines the action values to be displayed: | ||
* - DECODED: Displays the parameters of the action and the value field if the function is payable | ||
* - RAW: Only displays the base values of the action (value and data) | ||
* @default RAW | ||
*/ | ||
view?: ProposalActionsDecoderView; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
5 changes: 5 additions & 0 deletions
5
...omponents/proposal/proposalActions/proposalActionsDecoder/proposalActionsDecoder.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
describe('<ProposalActionsDecoder /> component', () => { | ||
it('', () => { | ||
// | ||
}); | ||
}); |
108 changes: 108 additions & 0 deletions
108
...les/components/proposal/proposalActions/proposalActionsDecoder/proposalActionsDecoder.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
import classNames from 'classnames'; | ||
import { useCallback, useEffect } from 'react'; | ||
import type { DeepPartial } from 'react-hook-form'; | ||
import { encodeFunctionData } from 'viem'; | ||
import { Button, clipboardUtils } from '../../../../../core'; | ||
import { useFormContext } from '../../../../hooks'; | ||
import { useGukModulesContext } from '../../../gukModulesProvider'; | ||
import type { IProposalAction } from '../proposalActionsDefinitions'; | ||
import { | ||
ProposalActionsDecoderMode, | ||
ProposalActionsDecoderView, | ||
type IProposalActionsDecoderProps, | ||
} from './proposalActionsDecoder.api'; | ||
import { ProposalActionsDecoderField } from './proposalActionsDecoderField/proposalActionsDecoderField'; | ||
import { ProposalActionsDecoderTextField } from './proposalActionsDecoderTextField'; | ||
import { proposalActionsDecoderUtils } from './proposalActionsDecoderUtils'; | ||
|
||
export const ProposalActionsDecoder: React.FC<IProposalActionsDecoderProps> = (props: IProposalActionsDecoderProps) => { | ||
const { | ||
action, | ||
formPrefix, | ||
mode = ProposalActionsDecoderMode.READ, | ||
view = ProposalActionsDecoderView.RAW, | ||
className, | ||
...otherProps | ||
} = props; | ||
const { value, data, inputData } = action; | ||
|
||
const { copy } = useGukModulesContext(); | ||
|
||
const { watch, setValue } = useFormContext<IProposalAction>(mode === ProposalActionsDecoderMode.EDIT); | ||
|
||
const dataFieldName = proposalActionsDecoderUtils.getFieldName('data', formPrefix) as 'data'; | ||
|
||
const updateEncodedData = useCallback( | ||
(formValues: DeepPartial<IProposalAction>) => { | ||
const functionParameters = formValues.inputData?.parameters?.map((parameter) => parameter?.value); | ||
const actionAbi = [{ type: 'function', name: inputData?.function, inputs: inputData?.parameters }]; | ||
let data = '0x'; | ||
|
||
try { | ||
data = encodeFunctionData({ abi: actionAbi, args: functionParameters }); | ||
} finally { | ||
// @ts-expect-error Limitation of react-hook-form, ignore error | ||
setValue(dataFieldName, data); | ||
} | ||
}, | ||
[inputData, dataFieldName, setValue], | ||
); | ||
|
||
useEffect(() => { | ||
if (mode !== ProposalActionsDecoderMode.EDIT || view !== ProposalActionsDecoderView.DECODED) { | ||
return; | ||
} | ||
|
||
const { unsubscribe } = watch((formValues, { name }) => | ||
name === dataFieldName ? undefined : updateEncodedData(formValues), | ||
); | ||
|
||
return () => unsubscribe(); | ||
}, [mode, watch, setValue, updateEncodedData, dataFieldName, view]); | ||
|
||
const handleCopyDataClick = () => clipboardUtils.copy(action.data); | ||
|
||
return ( | ||
<div className={classNames('flex w-full flex-col gap-3', className)} {...otherProps}> | ||
{(view === ProposalActionsDecoderView.RAW || action.inputData?.payable) && ( | ||
<ProposalActionsDecoderTextField | ||
fieldName="value" | ||
mode={mode} | ||
formPrefix={formPrefix} | ||
parameter={{ | ||
name: 'value', | ||
notice: copy.proposalActionsItemDecodedView.valueHelper, | ||
value: value, | ||
type: 'uint', | ||
}} | ||
/> | ||
)} | ||
<ProposalActionsDecoderTextField | ||
fieldName="data" | ||
mode={mode} | ||
formPrefix={formPrefix} | ||
parameter={{ name: 'data', value: data, type: 'bytes' }} | ||
className={view === ProposalActionsDecoderView.DECODED ? 'hidden' : undefined} | ||
component="textarea" | ||
/> | ||
{view === ProposalActionsDecoderView.RAW && mode === ProposalActionsDecoderMode.READ && ( | ||
<Button variant="tertiary" size="md" onClick={handleCopyDataClick} className="self-end"> | ||
{copy.proposalActionsItemRawView.copyButton} | ||
</Button> | ||
)} | ||
{view === ProposalActionsDecoderView.DECODED && | ||
inputData?.parameters.map((parameter, index) => ( | ||
<ProposalActionsDecoderField | ||
key={parameter.name} | ||
parameter={parameter} | ||
mode={mode} | ||
fieldName="value" | ||
formPrefix={proposalActionsDecoderUtils.getFieldName( | ||
`inputData.parameters.${index.toString()}`, | ||
formPrefix, | ||
)} | ||
/> | ||
))} | ||
</div> | ||
); | ||
}; |
5 changes: 5 additions & 0 deletions
5
...s/proposalActionsDecoder/proposalActionsDecoderField/proposalActionsDecoderField.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
describe('<proposalActionsDecoderField /> component', () => { | ||
it('', () => { | ||
// | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.