diff --git a/src/components/client/TransactionHeader.tsx b/src/components/client/TransactionHeader.tsx index ed38894..66be65e 100644 --- a/src/components/client/TransactionHeader.tsx +++ b/src/components/client/TransactionHeader.tsx @@ -36,7 +36,7 @@ export const TransactionHeader: React.FC<{ transaction: ITransaction }> = ({ const rpcEndpoint = useOptionsStore( (state) => state.transactionOptions.rpcEndpoint ); - const { results, set: setTransaction } = useTransactionStore( + const { results, set, clearTransaction } = useTransactionStore( (state) => state ); const setOptions = useOptionsStore((state) => state.set); @@ -51,7 +51,7 @@ export const TransactionHeader: React.FC<{ transaction: ITransaction }> = ({ flex="1" defaultValue={transaction.name} onChange={(value) => - setTransaction((state) => { + set((state) => { state.transaction.name = value; }) } @@ -69,7 +69,7 @@ export const TransactionHeader: React.FC<{ transaction: ITransaction }> = ({ icon={} variant="ghost" onClick={() => { - setTransaction((state) => { + set((state) => { Object.keys(state.uiState.instructions).forEach((id) => { state.uiState.instructions[id].expanded = true; }); @@ -83,7 +83,7 @@ export const TransactionHeader: React.FC<{ transaction: ITransaction }> = ({ icon={} variant="ghost" onClick={() => { - setTransaction((state) => { + set((state) => { Object.keys(state.uiState.instructions).forEach((id) => { state.uiState.instructions[id].expanded = false; }); @@ -108,7 +108,14 @@ export const TransactionHeader: React.FC<{ transaction: ITransaction }> = ({ } isDisabled> Download - }>Clear + } + onClick={() => { + clearTransaction(); + }} + > + Clear + diff --git a/src/components/header/Examples.tsx b/src/components/header/Examples.tsx index 144a94c..f438b7a 100644 --- a/src/components/header/Examples.tsx +++ b/src/components/header/Examples.tsx @@ -15,9 +15,12 @@ import { mapFromTransactionExt } from "../../models/external-mappers"; export const Example: React.FC = () => { const { publicKey: walletPublicKey } = useWallet(); - const setTransaction = useTransactionStore((state) => state.setTransaction); + const { clearTransaction, setTransaction } = useTransactionStore( + (state) => state + ); const loadExample = (name: string) => { + clearTransaction(); setTransaction( mapFromTransactionExt(EXAMPLES[name](walletPublicKey?.toBase58()!)) ); diff --git a/src/hooks/useTransactionStore.ts b/src/hooks/useTransactionStore.ts index 7beb9cb..f40f714 100644 --- a/src/hooks/useTransactionStore.ts +++ b/src/hooks/useTransactionStore.ts @@ -1,8 +1,11 @@ import produce from "immer"; import { WritableDraft } from "immer/dist/internal"; import create from "zustand"; +import { ITransaction } from "../models/internal-types"; import { addTo, IID, removeFrom } from "../models/sortable"; import { + DEFAULT_RESULTS, + DEFAULT_TRANSACTION, DEFAULT_TRANSACTION_STATE, DEFAULT_UI_INSTRUCTION_STATE, } from "../models/state-default"; @@ -36,26 +39,36 @@ export const useTransactionStore = create((set) => { saveState(state); } + const setTransaction = (transaction: ITransaction) => { + set( + produce((state: WritableDraft) => { + state.transaction = transaction; + state.uiState.instructions = transaction.instructions.order.reduce( + (acc, id) => { + acc[id] = DEFAULT_UI_INSTRUCTION_STATE; + return acc; + }, + {} as Record + ); + }) + ); + }; + return { ...state, set: (fn) => { set(produce(fn)); }, // define these helpers since they interact with different slices of state - setTransaction: (transaction) => { + clearTransaction: () => { + setTransaction(DEFAULT_TRANSACTION); set( produce((state: WritableDraft) => { - state.transaction = transaction; - state.uiState.instructions = transaction.instructions.order.reduce( - (acc, id) => { - acc[id] = DEFAULT_UI_INSTRUCTION_STATE; - return acc; - }, - {} as Record - ); + state.results = DEFAULT_RESULTS; }) ); }, + setTransaction, addInstruction: (instruction) => { set( produce((state: WritableDraft) => { diff --git a/src/models/state-default.ts b/src/models/state-default.ts index f60c5ed..a9db71c 100644 --- a/src/models/state-default.ts +++ b/src/models/state-default.ts @@ -76,7 +76,7 @@ export const DEFAUT_TRANSACTION_OPTIONS: ITransactionOptions = { pollingPeriod: 1_000, }; -const DEFAULT_TRANSACTION: ITransaction = { +export const DEFAULT_TRANSACTION: ITransaction = { name: "New Transcation", instructions: toSortableCollection([ { ...newInstruction(), accounts: toSortableCollection([newAccount()]) }, @@ -88,13 +88,15 @@ export const DEFAULT_UI_INSTRUCTION_STATE = { expanded: true, }; +export const DEFAULT_RESULTS = { + inProgress: false, + signature: "", + logs: ["Run a transaction to see logs"], +}; + export const DEFAULT_TRANSACTION_STATE: TransactionState = { transaction: DEFAULT_TRANSACTION, - results: { - inProgress: false, - signature: "", - logs: ["Run a transaction to see logs"], - }, + results: DEFAULT_RESULTS, uiState: { instructions: { [DEFAULT_TRANSACTION.instructions.order[0]]: DEFAULT_UI_INSTRUCTION_STATE, @@ -104,6 +106,7 @@ export const DEFAULT_TRANSACTION_STATE: TransactionState = { welcomeOpen: true, }, set: () => {}, // set by the hook + clearTransaction: () => {}, // set by the hook setTransaction: (_) => {}, // set by the hook addInstruction: (_) => {}, // set by the hook removeInstruction: (_) => {}, // set by the hook diff --git a/src/models/state-types.ts b/src/models/state-types.ts index 66b3ed6..afb7b94 100644 --- a/src/models/state-types.ts +++ b/src/models/state-types.ts @@ -49,6 +49,7 @@ export type TransactionState = { readonly results: IResults; readonly uiState: UIState; set: (fn: (state: Draft) => void) => void; + clearTransaction: () => void; setTransaction: (transaction: ITransaction) => void; addInstruction: (instruction: IInstruction) => void; removeInstruction: (instructionId: IID) => void;