Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(web-devtools): custom-context-input #1716

Merged
merged 4 commits into from
Oct 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import retrieveVariables from "@kleros/kleros-sdk/src/dataMappings/utils/retrieveVariables";
import { Field } from "@kleros/ui-components-library";
import { useMemo, useState } from "react";
import styled from "styled-components";
import { useDebounce } from "react-use";
import WithHelpTooltip from "components/WithHelpTooltip";

const Container = styled.div`
width: 100%;
display: flex;
flex-direction: column;
gap: 16px;
margin-top: 32px;
`;

const Header = styled.h2`
margin: 0;
`;

const InputContainer = styled.div`
display: flex;
gap: 16px;
flex-wrap: wrap;
`;
const VariableName = styled.p`
font-family: "Roboto Mono", monospace;
`;

// prevent duplicating input fields
const DisputeRequestParams = [
"arbitrator",
"arbitrable",
"arbitratorDisputeID",
"externalDisputeID",
"templateID",
"templateUri",
];

interface ICustomContextInputs {
dataMapping: string;
setCustomContext: (context: Record<string, string>) => void;
}
const CustomContextInputs: React.FC<ICustomContextInputs> = ({ dataMapping, setCustomContext }) => {
const [customContextInputs, setCustomContextInputs] = useState<Record<string, string>>();

const requiredVariables = useMemo(() => {
try {
return retrieveVariables(dataMapping);
} catch (error) {
console.error("Failed to parse dataMapping:", error);
return [];
}
}, [dataMapping]);

useDebounce(
() => {
if (!customContextInputs) return;
setCustomContext(customContextInputs);
},
300,
[customContextInputs]
);

return requiredVariables.length ? (
<Container>
<WithHelpTooltip tooltipMsg="These are additional variables required by the data mapping to be passed as initial context. Please ignore the variables that will come from the result of the preceeding data mappings">
<Header>Additional Context</Header>
</WithHelpTooltip>
{requiredVariables.map((variable, index) =>
DisputeRequestParams.includes(variable) ? null : (
<InputContainer key={`${variable}-${index}`}>
<VariableName>{variable}:</VariableName>
<Field
type="text"
name={variable}
value={customContextInputs?.[variable]}
onChange={(e) => {
setCustomContextInputs((prev) => ({ ...prev, [variable]: e.target.value }));
}}
placeholder="0x..."
/>
</InputContainer>
)
)}
</Container>
) : null;
};

export default CustomContextInputs;
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,17 @@ const StyledA = styled.a`
const presets = [
{
title: "Escrow",
txnHash: "0x85e60cb407c9a38e625263cc762ff4283d01f38201825e1d20109d8664cfa7d4",
txnHash: "0x2565b756e500240544f7fc36f938462c7efbbd2e343c57979f81fecdf1054e23",
chainId: 421614,
},
{
title: "Curated Lists",
txnHash: "0x6e5ad6f7436ef8570b50b0fbec76a11ccedbed85030c670e59d8f6617a499108",
txnHash: "0xa7981830bf8144ab2070f3a639bd36b204c4c48ee1fafef66abaf60272418ed4",
chainId: 421614,
},
{
title: "Trump-Biden",
txnHash: "0x9a3a420174f3c55c2b3eb2e77266777b74028b845e528a90142b5b57aafbdb90",
title: "Trump-Harris",
txnHash: "0x86db91678cf3f8c4503e37340cf2cd93bffcba84f9c43a98c090f6a4c76d8793",
chainId: 421614,
},
];
Expand Down
14 changes: 11 additions & 3 deletions web-devtools/src/app/(main)/dispute-template/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import ReactMarkdown from "components/ReactMarkdown";

import FetchDisputeRequestInput, { DisputeRequest } from "./FetchDisputeRequestInput";
import FetchFromIDInput from "./FetchFromIdInput";
import CustomContextInputs from "./CustomContextInputs";

const Container = styled.div`
height: auto;
Expand Down Expand Up @@ -105,6 +106,7 @@ const UpperContainer = styled.div`
`
)}
`;

const StyledForm = styled.form`
display: flex;
flex-direction: column;
Expand Down Expand Up @@ -150,6 +152,7 @@ const DisputeTemplateView = () => {
const [disputeDetails, setDisputeDetails] = useState<DisputeDetails | undefined>(undefined);
const [disputeTemplateInput, setDisputeTemplateInput] = useState<string>("");
const [dataMappingsInput, setDataMappingsInput] = useState<string>("");
const [customContext, setCustomContext] = useState<Record<string, string>>();

const [params, setParams] = useState<DisputeRequest>({
_arbitrable: "0x10f7A6f42Af606553883415bc8862643A6e63fdA",
Expand Down Expand Up @@ -178,7 +181,7 @@ const DisputeTemplateView = () => {
setLoading(true);

setTimeout(() => {
const initialContext = {
let initialContext = {
arbitrator: debouncedParams._arbitrator,
arbitrable: debouncedParams._arbitrable,
arbitratorDisputeID: debouncedParams._arbitratorDisputeID,
Expand All @@ -187,6 +190,8 @@ const DisputeTemplateView = () => {
templateUri: debouncedParams._templateUri,
};

if (customContext) initialContext = { ...initialContext, ...customContext };

const fetchData = async () => {
try {
const data = dataMappingsInput ? await executeActions(JSON.parse(dataMappingsInput), initialContext) : {};
Expand All @@ -210,7 +215,7 @@ const DisputeTemplateView = () => {
if (disputeTemplateInput || dataMappingsInput || debouncedParams) {
scheduleFetchData();
}
}, [disputeTemplateInput, dataMappingsInput, debouncedParams]);
}, [disputeTemplateInput, dataMappingsInput, debouncedParams, customContext]);

return (
<>
Expand Down Expand Up @@ -277,9 +282,12 @@ const DisputeTemplateView = () => {
name="_templateUri"
value={params._templateUri}
onChange={handleFormUpdate}
placeholder="ipfs://... (optional)"
placeholder="/ipfs/... (optional)"
/>
</StyledRow>
<StyledRow>
<CustomContextInputs dataMapping={dataMappingsInput} setCustomContext={setCustomContext} />
</StyledRow>
</StyledForm>
<div>
<FetchFromIDInput
Expand Down
2 changes: 1 addition & 1 deletion web-devtools/src/components/JSONEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,6 @@ const JSONEditor = (props: any) => {
}
}, [props]);

return <Container ref={refContainer}></Container>;
return <Container ref={refContainer} className={props.className}></Container>;
};
export default JSONEditor;
1 change: 0 additions & 1 deletion web-devtools/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
"./*"
],
"src*": [
"../../kleros-sdk/src/*",
"./*"
],
"svgs*": [
Expand Down
Loading