Skip to content

Commit

Permalink
* remove Proposal context for explicit prop passing.
Browse files Browse the repository at this point in the history
* Fix some typing issues
  • Loading branch information
oveddan committed Apr 22, 2024
1 parent 46e4ed2 commit b442da7
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 82 deletions.
85 changes: 27 additions & 58 deletions src/app/NewSafeProposal.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,26 @@
import { Field, FieldArray, Formik } from "formik";
import { SafeInformation } from "../components/SafeInformation";
import { Card, View, Text, Button, useToast } from "reshaped";
import {
SyntheticEvent,
createContext,
useCallback,
useEffect,
useState,
} from "react";
import { SyntheticEvent, useCallback, useEffect, useState } from "react";
import { Address, Hex, formatEther } from "viem";
import { validateAddress, validateETH } from "../utils/validators";
import { GenericField } from "../components/GenericField";
import { DataActionPreview } from "../components/DataActionPreview";
import Safe, { EthersAdapter } from "@safe-global/protocol-kit";
import { ethers } from "ethers";
import { contractNetworks } from "../chains";
import Safe from "@safe-global/protocol-kit";
import {
DEFAULT_ACTION_ITEM,
DEFAULT_PROPOSAL,
Proposal,
proposalSchema,
} from "../schemas/proposal";
import { useRedirectToProposalWithNewParams } from "../hooks/useSetParamsFromQuery";
import { useLoadProposalFromQuery } from "../hooks/useLoadProposalFromQuery";
import {
transformValuesFromWei,
transformValuesToWei,
} from "../utils/etherFormatting";
import { BrowserProvider } from "ethers";
import { useOutletContext } from "react-router-dom";
import { NetworkContext, SafeContext } from "../components/Contexts";
import { useUpdateProposal } from "../hooks/useUpdateProposalViaQuery";

const FormActionItem = ({
name,
Expand Down Expand Up @@ -62,24 +53,6 @@ const FormActionItem = ({
);
};

const createSafeAdapter = async ({
provider,
safeAddress,
}: {
provider: BrowserProvider;
safeAddress: Address;
}) => {
const ethAdapter = new EthersAdapter({
ethers,
signerOrProvider: await provider!.getSigner(),
});
return await Safe.create({
ethAdapter,
safeAddress,
contractNetworks,
});
};

const createSafeTransaction = async ({
proposal,
safe,
Expand Down Expand Up @@ -335,20 +308,19 @@ const ViewProposal = ({

const EditProposal = ({
proposal,
setProposal,
}: {
proposal: Proposal | undefined;
setProposal: (result: Proposal) => void;
setIsEditing: (editing: boolean) => void;
setProposal: (proposal: Proposal) => void;
}) => {
const redirectToEditedProposal = useRedirectToProposalWithNewParams();
const onSubmit = useCallback(
(result: Proposal) => {
const proposal = transformValuesToWei(result);
if (proposal) {
redirectToEditedProposal(proposal);
setProposal(proposal);
}
},
[redirectToEditedProposal]
[setProposal]
);

const defaultActions = proposal || DEFAULT_PROPOSAL;
Expand Down Expand Up @@ -410,11 +382,9 @@ const EditProposal = ({
);
};

export const ProposalContext = createContext<Proposal | undefined>(undefined);

export const NewSafeProposal = () => {
const [proposal, setProposal] = useState<undefined | Proposal>(
DEFAULT_PROPOSAL,
DEFAULT_PROPOSAL
);
const [isEditing, setIsEditing] = useState(true);

Expand All @@ -432,28 +402,27 @@ export const NewSafeProposal = () => {
setIsEditing(true);
evt.preventDefault();
},
[setIsEditing],
[setIsEditing]
);

const updateProposal = useUpdateProposal({ proposal });

return (
<ProposalContext.Provider value={proposal}>
<View paddingTop={4} paddingBottom={8} gap={8}>
<SafeInformation>
{isEditing && (
<EditProposal
proposal={proposal}
setProposal={setProposal}
setIsEditing={setIsEditing}
/>
)}
{!isEditing && proposal && (
<ViewProposal
proposal={proposal}
handleEditClicked={handleEditClicked}
/>
)}
</SafeInformation>
</View>
</ProposalContext.Provider>
<View paddingTop={4} paddingBottom={8} gap={8}>
<SafeInformation updateProposal={updateProposal}>
{isEditing && (
<EditProposal
proposal={proposal}
setProposal={updateProposal.replace}
/>
)}
{!isEditing && proposal && (
<ViewProposal
proposal={proposal}
handleEditClicked={handleEditClicked}
/>
)}
</SafeInformation>
</View>
);
};
4 changes: 4 additions & 0 deletions src/components/SafeInformation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { AddressView } from "../components/AddressView";
import { OwnerAction, SetOwnerModal } from "../components/SetOwnerModal";
import { useOutletContext } from "react-router-dom";
import { SafeContext } from "./Contexts";
import { UpdateProposal } from "../hooks/useUpdateProposalViaQuery";

const SafeInformationItem = ({
title,
Expand All @@ -27,8 +28,10 @@ const SafeInformationItem = ({

export const SafeInformation = ({
children,
updateProposal,
}: {
children?: React.ReactNode;
updateProposal: UpdateProposal;
}) => {
const [ownerAction, setOwnerAction] = useState<OwnerAction>();

Expand All @@ -42,6 +45,7 @@ export const SafeInformation = ({
setOwnerAction(undefined);
}}
action={ownerAction}
updatedProposal={updateProposal}
/>
)}
<Card>
Expand Down
39 changes: 27 additions & 12 deletions src/components/SetOwnerModal.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { SyntheticEvent, useContext } from "react";
import { SyntheticEvent } from "react";
import { Button, Modal, Text, View, useToast } from "reshaped";
import { AddressView } from "./AddressView";
import { Address } from "viem";
Expand All @@ -8,8 +8,7 @@ import { yupAddress } from "../utils/validators";
import { number, object } from "yup";
import { useOutletContext } from "react-router-dom";
import { SafeContext } from "./Contexts";
import { ProposalContext } from "../app/NewSafeProposal";
import { useUpdateProposalViaQuery } from "../hooks/useUpdateProposalViaQuery";
import { UpdateProposal } from "../hooks/useUpdateProposalViaQuery";

export type OwnerAction =
| undefined
Expand Down Expand Up @@ -42,11 +41,15 @@ const ButtonPanel = ({
</View>
);

const AddOwnerModalContent = ({ onClose }: { onClose: () => void }) => {
const AddOwnerModalContent = ({
onClose,
updateProposal: { addAction },
}: {
onClose: () => void;
updateProposal: UpdateProposal;
}) => {
const { safeInformation } = useOutletContext<SafeContext>();
const toast = useToast();
const updateProposalQuery = useUpdateProposalViaQuery();
const currentProposal = useContext(ProposalContext);

return (
<Formik
Expand All @@ -62,7 +65,7 @@ const AddOwnerModalContent = ({ onClose }: { onClose: () => void }) => {
ownerAddress: address,
threshold: threshold,
});
updateProposalQuery({
addAction({
data: addOwnerTx.data.data,
value: "0",
to: safeInformation.address,
Expand Down Expand Up @@ -96,12 +99,13 @@ const AddOwnerModalContent = ({ onClose }: { onClose: () => void }) => {
const RemoveOwnerModalContent = ({
onClose,
target,
updateProposal: { addAction },
}: {
onClose: () => void;
target: string;
updateProposal: UpdateProposal;
}) => {
const { safeInformation } = useOutletContext<SafeContext>();
const updateProposalViaQuery = useUpdateProposalViaQuery();
const toaster = useToast();

const onSubmitClick = async ({ threshold }: any) => {
Expand All @@ -110,13 +114,13 @@ const RemoveOwnerModalContent = ({
{
ownerAddress: target,
threshold: threshold,
},
}
);
if (!removeOwnerTx || !safeInformation) {
return;
}

updateProposalViaQuery({
addAction({
data: removeOwnerTx.data.data,
value: "0",
to: safeInformation.address,
Expand Down Expand Up @@ -158,16 +162,27 @@ const RemoveOwnerModalContent = ({
export const SetOwnerModal = ({
action,
onClose,
updatedProposal,
}: {
action: OwnerAction;
onClose: () => void;
updatedProposal: UpdateProposal;
}) => {
return (
<Modal active={!!action} onClose={onClose}>
{action?.type === "remove" && (
<RemoveOwnerModalContent onClose={onClose} target={action.address} />
<RemoveOwnerModalContent
onClose={onClose}
target={action.address}
updateProposal={updatedProposal}
/>
)}
{action?.type === "add" && (
<AddOwnerModalContent
onClose={onClose}
updateProposal={updatedProposal}
/>
)}
{action?.type === "add" && <AddOwnerModalContent onClose={onClose} />}
</Modal>
);
};
7 changes: 6 additions & 1 deletion src/hooks/useLoadProposalFromQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,12 @@ export const useLoadProposalFromQuery = () => {

console.log({ actions, txt: "setting proposal" });

setProposal({ actions, ...(nonce ? { [queryKeys.nonce]: nonce } : {}) });
const proposal: Proposal = {
actions,
...(nonce ? { nonce: parseInt(nonce) } : {}),
};

setProposal(proposal);
}
}, [params, setProposal]);

Expand Down
16 changes: 11 additions & 5 deletions src/hooks/useSetParamsFromQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,30 @@ import { Proposal } from "../schemas/proposal";
import { queryKeys } from "./useLoadProposalFromQuery";

export const useRedirectToProposalWithNewParams = () => {
const [_, setParams] = useSearchParams();
const [, setParams] = useSearchParams();

return useCallback(
(proposal: Proposal) => {
if (!proposal.actions?.length) {
return;
}
setParams({
[queryKeys.targets]: proposal.actions!.map((action) => action.to).join("|"),
[queryKeys.calldatas]: proposal.actions!.map((action) => action.data).join("|"),
[queryKeys.values]: proposal.actions!.map((action) => action.value).join("|"),
[queryKeys.targets]: proposal
.actions!.map((action) => action.to)
.join("|"),
[queryKeys.calldatas]: proposal
.actions!.map((action) => action.data)
.join("|"),
[queryKeys.values]: proposal
.actions!.map((action) => action.value)
.join("|"),
...(proposal.nonce
? {
[queryKeys.nonce]: proposal.nonce.toString(),
}
: {}),
});
},
[setParams],
[setParams]
);
};
23 changes: 17 additions & 6 deletions src/hooks/useUpdateProposalViaQuery.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,30 @@
import { useCallback, useContext } from "react";
import { useCallback } from "react";
import { Proposal } from "../schemas/proposal";
import { ProposalContext } from "../app/NewSafeProposal";
import { useRedirectToProposalWithNewParams } from "./useSetParamsFromQuery";

export const useUpdateProposalViaQuery = () => {
export type UpdateProposal = {
addAction: (newAction: NonNullable<Proposal["actions"]>[0]) => void;
replace: (proposal: Proposal) => void;
};
export const useUpdateProposal = ({
proposal,
}: {
proposal: Proposal | undefined;
}): UpdateProposal => {
const setParams = useRedirectToProposalWithNewParams();
const proposal = useContext(ProposalContext);

return useCallback(
const addAction = useCallback(
(newAction: NonNullable<Proposal["actions"]>[0]) => {
setParams({
actions: [...(proposal?.actions || []), newAction],
nonce: proposal?.nonce,
});
},
[proposal, setParams],
[proposal, setParams]
);

return {
addAction,
replace: setParams,
};
};

0 comments on commit b442da7

Please sign in to comment.