diff --git a/packages/website/src/app/deploy/layout.tsx b/packages/website/src/app/deploy/layout.tsx
index 277644303..2c75e9045 100644
--- a/packages/website/src/app/deploy/layout.tsx
+++ b/packages/website/src/app/deploy/layout.tsx
@@ -1,11 +1,15 @@
'use client';
+import dynamic from 'next/dynamic';
import { ReactNode } from 'react';
import { Box, Flex, useBreakpointValue } from '@chakra-ui/react';
import { usePathname } from 'next/navigation';
import { links } from '@/constants/links';
import { NavLink } from '@/components/NavLink';
-import WithSafe from '@/features/Deploy/WithSafe';
+
+const NoSSRWithSafe = dynamic(() => import('@/features/Deploy/WithSafe'), {
+ ssr: false,
+});
export default function DeployLayout({ children }: { children: ReactNode }) {
const pathname = usePathname();
@@ -47,7 +51,7 @@ export default function DeployLayout({ children }: { children: ReactNode }) {
- {children}
+ {children}
);
}
diff --git a/packages/website/src/components/EditableAutocompleteInput.tsx b/packages/website/src/components/EditableAutocompleteInput.tsx
index 0e3ac01fa..632c3c344 100644
--- a/packages/website/src/components/EditableAutocompleteInput.tsx
+++ b/packages/website/src/components/EditableAutocompleteInput.tsx
@@ -109,7 +109,6 @@ export function EditableAutocompleteInput(props: {
const editableInputRef = useRef();
function tabToNext() {
- console.log('tabdata trigger tabtonext');
const tabElements = Array.from(
document
// Get all elements that can be focusable
@@ -144,10 +143,6 @@ export function EditableAutocompleteInput(props: {
(e: any) => e === editableInputRef.current
);
- //console.log('tabdata current index', currentIndex);
- //console.log('tabdata', editableInputRef)
- //console.log('tabdata', tabElements);
-
const nextIndex = (currentIndex + 1) % tabElements.length;
tabElements[nextIndex].focus();
}
@@ -201,7 +196,6 @@ export function EditableAutocompleteInput(props: {
onEdit={() => setIsEditing(true)}
onBlur={() => {
finishEdit();
- tabToNext();
}}
onKeyDown={handleKey}
onChange={(value) => {
@@ -243,15 +237,14 @@ export function EditableAutocompleteInput(props: {
key={index}
item={item}
filterInput={filterInput}
- selected={item.label === pendingItem}
- isVisible={isEditing && filteredItems.length > 0}
onMouseOver={() => setPendingItem(item.label)}
+ onMouseDown={(evt: any) => {
+ evt.preventDefault();
+ }}
onClick={() => {
- console.log('tabdata click');
setPendingItem(item.label);
setFilterInput(item.label);
tabToNext();
- console.log('tabdata end');
}}
internalRef={
(item.label === pendingItem
@@ -271,10 +264,9 @@ export function EditableAutocompleteInput(props: {
function AutocompleteOption(props: {
item: { label: string; secondary: string };
filterInput: string;
- selected?: boolean;
onMouseOver: () => void;
+ onMouseDown: (evt: any) => void;
onClick: () => void;
- isVisible: boolean;
// eslint-disable-next-line no-undef
internalRef: React.MutableRefObject | undefined;
}) {
@@ -287,21 +279,13 @@ function AutocompleteOption(props: {
{
- evt.preventDefault();
- props.onClick();
- }}
+ onMouseDown={(evt: any) => props.onMouseDown(evt)}
+ onClick={props.onClick}
background="black"
px="2"
pb="1"
>
- {
- evt.preventDefault();
- props.onClick();
- }}
- gap={0}
- >
+
{matched.map((p, i) => [
{p},
i < matched.length - 1 ? {props.filterInput} : [],
diff --git a/packages/website/src/features/Deploy/QueueTransactionsPage.tsx b/packages/website/src/features/Deploy/QueueTransactionsPage.tsx
index fb13277b3..c93ed0699 100644
--- a/packages/website/src/features/Deploy/QueueTransactionsPage.tsx
+++ b/packages/website/src/features/Deploy/QueueTransactionsPage.tsx
@@ -1,6 +1,6 @@
'use client';
-import { AddIcon, MinusIcon } from '@chakra-ui/icons';
+import { AddIcon } from '@chakra-ui/icons';
import {
Alert,
AlertDescription,
@@ -18,9 +18,11 @@ import {
Tooltip,
useToast,
Text,
+ IconButton,
+ Flex,
} from '@chakra-ui/react';
-import _ from 'lodash';
-import { useState } from 'react';
+import { CloseIcon } from '@chakra-ui/icons';
+import { useEffect, useState } from 'react';
import { useRouter } from 'next/navigation';
import {
Abi,
@@ -42,6 +44,11 @@ import { makeMultisend } from '@/helpers/multisend';
import { DisplayedTransaction } from './DisplayedTransaction';
import NoncePicker from './NoncePicker';
+type IdentifiableTxn = {
+ txn: Omit;
+ id: string;
+};
+
export default function QueueTransactionsPage() {
return ;
}
@@ -51,9 +58,11 @@ function QueueTransactions() {
const router = useRouter();
const [target, setTarget] = useState('');
- const [queuedTxns, setQueuedTxns] = useState<
- Omit[]
- >([null as any]);
+
+ const [lastQueuedTxnsId, setLastQueuedTxnsId] = useState(0);
+ const [queuedIdentifiableTxns, setQueuedIdentifiableTxns] = useState<
+ IdentifiableTxn[]
+ >([{ txn: null as any, id: String(lastQueuedTxnsId) }]);
const [pickedNonce, setPickedNonce] = useState(null);
@@ -63,6 +72,8 @@ function QueueTransactions() {
`${currentSafe?.chainId}-${settings.preset}`
);
+ const queuedTxns = queuedIdentifiableTxns.map((item) => item.txn);
+
const multisendTxn =
queuedTxns.indexOf(null as any) === -1
? makeMultisend(
@@ -127,10 +138,29 @@ function QueueTransactions() {
i: number,
txn: Omit
) {
- queuedTxns[i] = txn;
- setQueuedTxns(_.clone(queuedTxns));
+ setQueuedIdentifiableTxns((prev) => {
+ const result = [...prev];
+ result[i].txn = txn;
+ return result;
+ });
}
+ const removeQueuedTxn = (i: number) => {
+ setQueuedIdentifiableTxns((prev) => {
+ const result = [...prev];
+ result.splice(i, 1);
+ return result;
+ });
+ };
+
+ const addQueuedTxn = () => {
+ setQueuedIdentifiableTxns((prev) => [
+ ...prev,
+ { txn: {}, id: String(lastQueuedTxnsId + 1) },
+ ]);
+ setLastQueuedTxnsId((prev) => prev + 1);
+ };
+
const txnHasError = !!txnInfo.txnResults.filter((r) => r?.error).length;
console.log('TXN HAS ERROR', txnHasError);
@@ -158,6 +188,17 @@ function QueueTransactions() {
const disableExecute =
!multisendTxn || txnHasError || !!stager.execConditionFailed;
+ console.log('xxx cannonInfo: ', cannonInfo);
+
+ useEffect(() => {
+ if (!cannonInfo.contracts) {
+ setQueuedIdentifiableTxns([
+ { txn: null as any, id: String(lastQueuedTxnsId + 1) },
+ ]);
+ setLastQueuedTxnsId((prev) => prev + 1);
+ }
+ }, [cannonInfo.contracts]);
+
return (
@@ -182,7 +223,7 @@ function QueueTransactions() {
connected wallet.
- {cannonInfo.pkgUrl && !cannonInfo.contracts && (
+ {!isAddress(target) && cannonInfo.pkgUrl && !cannonInfo.contracts && (
@@ -193,18 +234,32 @@ function QueueTransactions() {
)}
- {cannonInfo.contracts && (
+ {!isAddress(target) && cannonInfo.contracts && (
Transactions
- {queuedTxns.map((_, i) => (
-
- updateQueuedTxn(i, txn as any)}
- />
+ {queuedIdentifiableTxns.map((queuedIdentifiableTxn, i) => (
+
+
+ updateQueuedTxn(i, txn as any)}
+ />
+ {queuedIdentifiableTxns.length > 1 && (
+
+ }
+ aria-label={'Remove provider'}
+ onClick={() => removeQueuedTxn(i)}
+ />
+
+ )}
+
{txnInfo.txnResults &&
- txnInfo.txnResults.length === queuedTxns.length &&
+ txnInfo.txnResults.length === queuedIdentifiableTxns.length &&
txnInfo.txnResults[i] &&
txnInfo.txnResults[i]?.error && (
@@ -215,7 +270,7 @@ function QueueTransactions() {
: txnInfo.txnResults[i]?.error}
)}
-
+
))}
}
- onClick={() => setQueuedTxns(_.clone(queuedTxns.concat([{}])))}
+ onClick={() => addQueuedTxn()}
>
Add Transaction
- {queuedTxns.length > 1 && (
- }
- onClick={() =>
- setQueuedTxns(
- _.clone(queuedTxns.slice(0, queuedTxns.length - 1))
- )
- }
- >
- Remove Transaction
-
- )}
)}
@@ -256,6 +293,8 @@ function QueueTransactions() {
Value
updateQueuedTxn(0, {
...queuedTxns[0],
@@ -273,6 +312,8 @@ function QueueTransactions() {
Transaction Data
updateQueuedTxn(0, {
diff --git a/packages/website/src/features/Deploy/SafeAddressInput.tsx b/packages/website/src/features/Deploy/SafeAddressInput.tsx
index ae3229d43..2c2366a91 100644
--- a/packages/website/src/features/Deploy/SafeAddressInput.tsx
+++ b/packages/website/src/features/Deploy/SafeAddressInput.tsx
@@ -165,6 +165,7 @@ export function SafeAddressInput() {
<>