Skip to content

Commit 7bdaabc

Browse files
committed
handle address array
1 parent 25a5bb4 commit 7bdaabc

File tree

9 files changed

+264
-81
lines changed

9 files changed

+264
-81
lines changed

apps/dashboard/src/components/contract-components/contract-deploy-form/custom-contract.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,10 @@ type CustomContractDeploymentFormData = {
8484

8585
interface ContractRef {
8686
ref: {
87-
publisher: string;
87+
publisherAddress: string;
8888
version: string;
8989
contractId: string;
90-
};
90+
}[];
9191
}
9292

9393
export type CustomContractDeploymentForm =

apps/dashboard/src/components/contract-components/contract-publish-form/contract-params-fieldset.tsx

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import {
2525
Heading,
2626
Text,
2727
} from "tw-components";
28-
import { RefContractInput } from "./ref-input";
28+
import { RefInputFieldset } from "./ref-input-fieldset";
2929

3030
interface ContractParamsFieldsetProps {
3131
deployParams: readonly AbiParameter[];
@@ -45,27 +45,37 @@ export const ContractParamsFieldset: React.FC<ContractParamsFieldsetProps> = ({
4545
setIsCustomInputEnabled((prev) => {
4646
const updated = [...prev];
4747
updated[index] = !updated[index];
48+
49+
// Clear values accordingly when toggling between input types
50+
if (updated[index]) {
51+
form.setValue(
52+
`constructorParams.${deployParams[index]?.name || "*"}.ref.refType`,
53+
deployParams[index]?.type,
54+
);
55+
56+
form.setValue(
57+
`constructorParams.${deployParams[index]?.name || "*"}.defaultValue`,
58+
"",
59+
{
60+
shouldDirty: true,
61+
},
62+
);
63+
} else {
64+
form.setValue(
65+
`constructorParams.${deployParams[index]?.name || "*"}.ref.refType`,
66+
"",
67+
);
68+
form.setValue(
69+
`constructorParams.${deployParams[index]?.name || "*"}.ref`,
70+
"",
71+
{
72+
shouldDirty: true,
73+
},
74+
);
75+
}
76+
4877
return updated;
4978
});
50-
51-
// Clear values accordingly when toggling between input types
52-
if (isCustomInputEnabled[index]) {
53-
form.setValue(
54-
`constructorParams.${deployParams[index]?.name || "*"}.defaultValue`,
55-
"",
56-
{
57-
shouldDirty: true,
58-
},
59-
);
60-
} else {
61-
form.setValue(
62-
`constructorParams.${deployParams[index]?.name || "*"}.ref`,
63-
"",
64-
{
65-
shouldDirty: true,
66-
},
67-
);
68-
}
6979
};
7080

7181
return (
@@ -150,9 +160,7 @@ export const ContractParamsFieldset: React.FC<ContractParamsFieldsetProps> = ({
150160
{!isCustomInputEnabled[idx] ? (
151161
<>
152162
<SolidityInput
153-
solidityType={
154-
param.type === "address" ? "string" : param.type
155-
}
163+
solidityType={param.type}
156164
placeholder={
157165
isMobile ||
158166
paramTemplateValues?.[0]?.value ===
@@ -168,10 +176,11 @@ export const ContractParamsFieldset: React.FC<ContractParamsFieldsetProps> = ({
168176
/>
169177
</>
170178
) : (
171-
<RefContractInput param={param} />
179+
<RefInputFieldset param={param} />
172180
)}
173181

174-
{param.type === "address" && (
182+
{(param.type === "address" ||
183+
param.type === "address[]") && (
175184
<Checkbox
176185
isChecked={isCustomInputEnabled[idx]}
177186
onChange={() => handleToggleCustomInput(idx)}

apps/dashboard/src/components/contract-components/contract-publish-form/impl-params-fieldset.tsx

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import {
2121
Heading,
2222
Text,
2323
} from "tw-components";
24-
import { RefContractImplInput } from "./ref-input-impl";
24+
import { RefInputImplFieldset } from "./ref-input-impl-fieldset";
2525

2626
interface ImplementationParamsFieldsetProps {
2727
implParams: readonly AbiParameter[];
@@ -41,27 +41,35 @@ export const ImplementationParamsFieldset: React.FC<
4141
setIsCustomInputEnabled((prev) => {
4242
const updated = [...prev];
4343
updated[index] = !updated[index];
44+
45+
// Clear or set values accordingly when toggling between input types
46+
if (updated[index]) {
47+
form.setValue(
48+
`implConstructorParams.${implParams[index]?.name || "*"}.ref.refType`,
49+
implParams[index]?.type,
50+
);
51+
form.setValue(
52+
`implConstructorParams.${implParams[index]?.name || "*"}.defaultValue`,
53+
"",
54+
{
55+
shouldDirty: true,
56+
},
57+
);
58+
} else {
59+
form.setValue(
60+
`implConstructorParams.${implParams[index]?.name || "*"}.ref.refType`,
61+
"",
62+
);
63+
form.setValue(
64+
`implConstructorParams.${implParams[index]?.name || "*"}.ref`,
65+
"",
66+
{
67+
shouldDirty: true,
68+
},
69+
);
70+
}
4471
return updated;
4572
});
46-
47-
// Clear values accordingly when toggling between input types
48-
if (isCustomInputEnabled[index]) {
49-
form.setValue(
50-
`implConstructorParams.${implParams[index]?.name || "*"}.defaultValue`,
51-
"",
52-
{
53-
shouldDirty: true,
54-
},
55-
);
56-
} else {
57-
form.setValue(
58-
`implConstructorParams.${implParams[index]?.name || "*"}.ref`,
59-
"",
60-
{
61-
shouldDirty: true,
62-
},
63-
);
64-
}
6573
};
6674

6775
return (
@@ -126,7 +134,7 @@ export const ImplementationParamsFieldset: React.FC<
126134
/>
127135
</>
128136
) : (
129-
<RefContractImplInput param={param} />
137+
<RefInputImplFieldset param={param} />
130138
)}
131139

132140
{param.type === "address" && (
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { Box, Flex, Icon } from "@chakra-ui/react";
2+
import type { AbiParameter } from "abitype";
3+
import { PlusIcon } from "lucide-react";
4+
import { useFieldArray, useFormContext } from "react-hook-form";
5+
import { Button, Text } from "tw-components";
6+
import { RefContractInput } from "./ref-input";
7+
8+
interface RefInputFieldsetProps {
9+
param: AbiParameter;
10+
}
11+
12+
export const RefInputFieldset: React.FC<RefInputFieldsetProps> = ({
13+
param,
14+
}) => {
15+
const form = useFormContext();
16+
17+
const { fields, append, remove } = useFieldArray({
18+
name: `constructorParams.${param.name ? param.name : "*"}.ref.contracts`,
19+
control: form.control,
20+
});
21+
22+
return (
23+
<Flex gap={8} direction="column" as="fieldset">
24+
<Flex gap={2} direction="column">
25+
<Text>Set ref contract for this param.</Text>
26+
</Flex>
27+
<Flex flexDir="column" gap={4}>
28+
{fields.map((item, index) => (
29+
<RefContractInput
30+
key={item.id}
31+
remove={remove}
32+
index={index}
33+
param={param}
34+
/>
35+
))}
36+
<Box>
37+
<Button
38+
type="button"
39+
size="sm"
40+
colorScheme="primary"
41+
borderRadius="md"
42+
leftIcon={<Icon as={PlusIcon} />}
43+
isDisabled={param.type === "address" && fields.length >= 1}
44+
onClick={() =>
45+
append({
46+
contractId: "",
47+
version: "",
48+
publisherAddress: "",
49+
})
50+
}
51+
>
52+
Add Ref
53+
</Button>
54+
</Box>
55+
</Flex>
56+
</Flex>
57+
);
58+
};
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { Box, Flex, Icon } from "@chakra-ui/react";
2+
import type { AbiParameter } from "abitype";
3+
import { PlusIcon } from "lucide-react";
4+
import { useFieldArray, useFormContext } from "react-hook-form";
5+
import { Button, Text } from "tw-components";
6+
import { RefContractImplInput } from "./ref-input-impl";
7+
8+
interface RefInputImplFieldsetProps {
9+
param: AbiParameter;
10+
}
11+
12+
export const RefInputImplFieldset: React.FC<RefInputImplFieldsetProps> = ({
13+
param,
14+
}) => {
15+
const form = useFormContext();
16+
17+
const { fields, append, remove } = useFieldArray({
18+
name: `implConstructorParams.${param.name ? param.name : "*"}.ref.contracts`,
19+
control: form.control,
20+
});
21+
22+
return (
23+
<Flex gap={8} direction="column" as="fieldset">
24+
<Flex gap={2} direction="column">
25+
<Text>Set ref contract for this param.</Text>
26+
</Flex>
27+
<Flex flexDir="column" gap={4}>
28+
{fields.map((item, index) => (
29+
<RefContractImplInput
30+
key={item.id}
31+
remove={remove}
32+
index={index}
33+
param={param}
34+
/>
35+
))}
36+
<Box>
37+
<Button
38+
type="button"
39+
size="sm"
40+
colorScheme="primary"
41+
borderRadius="md"
42+
leftIcon={<Icon as={PlusIcon} />}
43+
isDisabled={param.type === "address" && fields.length >= 1}
44+
onClick={() =>
45+
append({
46+
contractId: "",
47+
version: "",
48+
publisherAddress: "",
49+
})
50+
}
51+
>
52+
Add Ref
53+
</Button>
54+
</Box>
55+
</Flex>
56+
</Flex>
57+
);
58+
};

apps/dashboard/src/components/contract-components/contract-publish-form/ref-input-impl.tsx

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,43 @@ import {
22
Divider,
33
Flex,
44
FormControl,
5+
Icon,
6+
IconButton,
57
Input,
68
Select,
79
Skeleton,
810
} from "@chakra-ui/react";
911
import type { AbiParameter } from "abitype";
12+
import { TrashIcon } from "lucide-react";
1013
import { useFormContext } from "react-hook-form";
1114
import { FormLabel } from "tw-components";
1215
import { useAllVersions, usePublishedContractsQuery } from "../hooks";
1316

1417
interface RefContractImplInputProps {
1518
param: AbiParameter;
19+
index: number;
20+
remove: (index: number) => void;
1621
}
1722

1823
export const RefContractImplInput: React.FC<RefContractImplInputProps> = ({
1924
param,
25+
index,
26+
remove,
2027
}) => {
2128
const form = useFormContext();
2229

2330
const publishedContractsQuery = usePublishedContractsQuery(
2431
form.watch(
25-
`implConstructorParams.${param.name ? param.name : "*"}.ref.publisherAddress`,
32+
`implConstructorParams.${param.name ? param.name : "*"}.ref.contracts.${index}.publisherAddress`,
2633
),
2734
);
2835

2936
const allVersions = useAllVersions(
3037
form.watch(
31-
`implConstructorParams.${param.name ? param.name : "*"}.ref.publisherAddress`,
38+
`implConstructorParams.${param.name ? param.name : "*"}.ref.contracts.${index}.publisherAddress`,
3239
),
3340
form.watch(
34-
`implConstructorParams.${param.name ? param.name : "*"}.ref.contractId`,
41+
`implConstructorParams.${param.name ? param.name : "*"}.ref.contracts.${index}.contractId`,
3542
),
3643
);
3744

@@ -48,7 +55,7 @@ export const RefContractImplInput: React.FC<RefContractImplInputProps> = ({
4855
gap={1}
4956
isInvalid={
5057
!!form.getFieldState(
51-
`implConstructorParams.${param.name ? param.name : "*"}.ref.publisherAddress`,
58+
`implConstructorParams.${param.name ? param.name : "*"}.ref.contracts.${index}.publisherAddress`,
5259
form.formState,
5360
).error
5461
}
@@ -57,7 +64,7 @@ export const RefContractImplInput: React.FC<RefContractImplInputProps> = ({
5764
<Input
5865
placeholder="Address or ENS"
5966
{...form.register(
60-
`implConstructorParams.${param.name ? param.name : "*"}.ref.publisherAddress`,
67+
`implConstructorParams.${param.name ? param.name : "*"}.ref.contracts.${index}.publisherAddress`,
6168
)}
6269
/>
6370
</FormControl>
@@ -73,7 +80,7 @@ export const RefContractImplInput: React.FC<RefContractImplInputProps> = ({
7380
<Select
7481
isDisabled={(publishedContractsQuery?.data || []).length === 0}
7582
{...form.register(
76-
`implConstructorParams.${param.name ? param.name : "*"}.ref.contractId`,
83+
`implConstructorParams.${param.name ? param.name : "*"}.ref.contracts.${index}.contractId`,
7784
)}
7885
placeholder={
7986
publishedContractsQuery.isFetched &&
@@ -101,7 +108,7 @@ export const RefContractImplInput: React.FC<RefContractImplInputProps> = ({
101108
w="full"
102109
isDisabled={!allVersions.data}
103110
{...form.register(
104-
`implConstructorParams.${param.name ? param.name : "*"}.ref.version`,
111+
`implConstructorParams.${param.name ? param.name : "*"}.ref.contracts.${index}.version`,
105112
)}
106113
borderRadius="lg"
107114
>
@@ -114,6 +121,12 @@ export const RefContractImplInput: React.FC<RefContractImplInputProps> = ({
114121
</Select>
115122
</Skeleton>
116123
</FormControl>
124+
<IconButton
125+
icon={<Icon as={TrashIcon} boxSize={5} />}
126+
aria-label="Remove row"
127+
onClick={() => remove(index)}
128+
alignSelf="end"
129+
/>
117130
</Flex>
118131
<Divider />
119132
</Flex>

0 commit comments

Comments
 (0)