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

Refactor/sdk and voting tab improvements #1894

Merged
merged 10 commits into from
Feb 17, 2025
22 changes: 17 additions & 5 deletions kleros-sdk/src/dataMappings/utils/populateTemplate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,23 @@ export const populateTemplate = (mustacheTemplate: string, data: any): DisputeDe
throw validation.error;
}

// Filter out any existing answer with id 0 and add our standard Refuse to Arbitrate option
(dispute as DisputeDetails).answers = [
RefuseToArbitrateAnswer,
...((dispute as DisputeDetails).answers.filter((answer) => answer.id && BigInt(answer.id) !== BigInt(0)) || []),
];
return findAndUpdateRTA(dispute);
};

// Filter out any existing answer with id 0 and add customised Refuse to Arbitrate option
const findAndUpdateRTA = (dispute: DisputeDetails) => {
const templateRTAIndex = (dispute as DisputeDetails).answers.findIndex(
(answer) => answer.id && BigInt(answer.id) === BigInt(0)
);

if (templateRTAIndex !== -1) {
dispute.answers[templateRTAIndex] = {
...RefuseToArbitrateAnswer,
description: dispute.answers[templateRTAIndex].description ?? RefuseToArbitrateAnswer.description,
};
} else {
dispute.answers = [RefuseToArbitrateAnswer, ...dispute.answers];
}

return dispute;
};
29 changes: 14 additions & 15 deletions kleros-sdk/test/getDispute.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,14 @@ describe("getDispute", () => {
expect(result?.answers[2].id).toBe("0x2");
});

it("should overwrite existing answer with id 0x0 or 0x00", async () => {
it("should only overwrite existing answer with id 0x0 or 0x00's title and not overwrite description", async () => {
const customRTAAnswer = {
id: "0x0",
title: "Custom Refuse Title",
description: "Custom Refuse Description",
reserved: true,
};

// Test with 0x0
const mockTemplate0x0 = {
disputeTemplate: {
Expand All @@ -114,12 +121,7 @@ describe("getDispute", () => {
description: "Test Description",
question: "Test Question",
answers: [
{
id: "0x0",
title: "Custom Refuse Title",
description: "Custom Refuse Description",
reserved: true,
},
customRTAAnswer,
{
id: "0x1",
title: "Yes",
Expand All @@ -145,7 +147,8 @@ describe("getDispute", () => {
});

expect(result?.answers).toHaveLength(2);
expect(result?.answers[0]).toEqual(standardRefuseToArbitrateAnswer);
expect(result?.answers[0].title).toEqual(standardRefuseToArbitrateAnswer.title);
expect(result?.answers[0].description).toEqual(customRTAAnswer.description);
expect(result?.answers[1].id).toBe("0x1");

// Test with 0x00
Expand All @@ -156,12 +159,7 @@ describe("getDispute", () => {
description: "Test Description",
question: "Test Question",
answers: [
{
id: "0x00",
title: "Custom Refuse Title",
description: "Custom Refuse Description",
reserved: true,
},
customRTAAnswer,
{
id: "0x1",
title: "Yes",
Expand All @@ -186,7 +184,8 @@ describe("getDispute", () => {
});

expect(result?.answers).toHaveLength(2);
expect(result?.answers[0]).toEqual(standardRefuseToArbitrateAnswer);
expect(result?.answers[0].title).toEqual(standardRefuseToArbitrateAnswer.title);
expect(result?.answers[0].description).toEqual(customRTAAnswer.description);
expect(result?.answers[1].id).toBe("0x1");
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React, { useCallback, useState } from "react";
import React, { useCallback, useMemo, useState } from "react";
import styled from "styled-components";

import ReactMarkdown from "react-markdown";
import { useParams } from "react-router-dom";

import { Button } from "@kleros/ui-components-library";
import { Button, Tooltip } from "@kleros/ui-components-library";

import { usePopulatedDisputeData } from "hooks/queries/usePopulatedDisputeData";
import { isUndefined } from "utils/index";
Expand All @@ -17,6 +17,8 @@ import { Answer } from "@kleros/kleros-sdk";
const MainContainer = styled.div`
width: 100%;
height: auto;
display: flex;
flex-direction: column;
`;

const OptionsContainer = styled.div`
Expand All @@ -40,6 +42,9 @@ const RefuseToArbitrateContainer = styled.div`
justify-content: center;
`;

const StyledEnsureChain = styled(EnsureChain)`
align-self: center;
`;
interface IOptions {
arbitrable: `0x${string}`;
handleSelection: (arg0: bigint) => Promise<void>;
Expand All @@ -53,6 +58,12 @@ const Options: React.FC<IOptions> = ({ arbitrable, handleSelection, justificatio
const [chosenOption, setChosenOption] = useState(BigInt(-1));
const [isSending, setIsSending] = useState(false);

// if RTA not found in dispute.answers, show RTA. shows RTA in case of invalid dispute too
const showRTA = useMemo(
() => isUndefined(disputeDetails?.answers?.find((answer) => BigInt(answer.id) === BigInt(0))),
[disputeDetails]
);

const onClick = useCallback(
async (id: bigint) => {
setIsSending(true);
Expand All @@ -71,32 +82,38 @@ const Options: React.FC<IOptions> = ({ arbitrable, handleSelection, justificatio
{!isUndefined(justification) && !isUndefined(setJustification) ? (
<JustificationArea {...{ justification, setJustification }} />
) : null}
<OptionsContainer>
{disputeDetails?.answers?.map((answer: Answer) => {
return (
<EnsureChain key={answer.title}>
<Button
text={answer.title}
disabled={isSending}
isLoading={chosenOption === BigInt(answer.id)}
onClick={() => onClick(BigInt(answer.id))}
/>
</EnsureChain>
);
})}
</OptionsContainer>
{isUndefined(disputeDetails?.answers) ? null : (
<StyledEnsureChain>
<OptionsContainer>
{disputeDetails?.answers?.map((answer: Answer) => {
return (
<Tooltip text={answer.description} key={answer.title}>
<Button
text={answer.title}
disabled={isSending}
isLoading={chosenOption === BigInt(answer.id)}
onClick={() => onClick(BigInt(answer.id))}
/>
</Tooltip>
);
})}
</OptionsContainer>
</StyledEnsureChain>
)}
</MainContainer>
<RefuseToArbitrateContainer>
<EnsureChain>
<Button
variant="secondary"
text="Refuse to Arbitrate"
disabled={isSending}
isLoading={chosenOption === BigInt(0)}
onClick={() => onClick(BigInt(0))}
/>
</EnsureChain>
</RefuseToArbitrateContainer>
{showRTA ? (
<RefuseToArbitrateContainer>
<EnsureChain>
<Button
variant="secondary"
text="Refuse to Arbitrate"
disabled={isSending}
isLoading={chosenOption === BigInt(0)}
onClick={() => onClick(BigInt(0))}
/>
</EnsureChain>
</RefuseToArbitrateContainer>
) : null}
</>
) : null;
};
Expand Down
21 changes: 14 additions & 7 deletions web/src/pages/Cases/CaseDetails/Voting/Classic/Reveal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import InfoCard from "components/InfoCard";

import JustificationArea from "./JustificationArea";
import { Answer } from "@kleros/kleros-sdk";
import { EnsureChain } from "components/EnsureChain";

const Container = styled.div`
width: 100%;
Expand All @@ -35,6 +36,10 @@ const StyledButton = styled(Button)`
margin: 16px auto;
`;

const StyledEnsureChain = styled(EnsureChain)`
margin: 8px auto;
`;

const ReactMarkdownWrapper = styled.div``;
interface IReveal {
arbitrable: `0x${string}`;
Expand Down Expand Up @@ -106,13 +111,15 @@ const Reveal: React.FC<IReveal> = ({ arbitrable, voteIDs, setIsOpen, commit, isR
<ReactMarkdown>{disputeDetails?.question ?? ""}</ReactMarkdown>
</ReactMarkdownWrapper>
<JustificationArea {...{ justification, setJustification }} />
<StyledButton
variant="secondary"
text="Justify & Reveal"
disabled={isSending || isUndefined(disputeDetails)}
isLoading={isSending}
onClick={handleReveal}
/>
<StyledEnsureChain>
<StyledButton
variant="secondary"
text="Justify & Reveal"
disabled={isSending || isUndefined(disputeDetails)}
isLoading={isSending}
onClick={handleReveal}
/>
</StyledEnsureChain>
</>
) : (
<StyledInfoCard msg="Your vote was successfully commited, please wait until reveal period to reveal it." />
Expand Down
3 changes: 2 additions & 1 deletion web/src/utils/getVoteChoice.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Answer } from "@kleros/kleros-sdk";
import { isUndefined } from ".";
import { RefuseToArbitrateAnswer } from "@kleros/kleros-sdk/src/dataMappings/utils/disputeDetailsSchema";

export const getVoteChoice = (vote: string, answers: Answer[]) => {
// answer.id is hexadecimal number
Expand All @@ -8,6 +9,6 @@ export const getVoteChoice = (vote: string, answers: Answer[]) => {
if (!isUndefined(selectedAnswer)) {
return selectedAnswer.title;
} else {
return `Answer 0x${vote}`;
return BigInt(vote) === BigInt(0) ? RefuseToArbitrateAnswer.title : `Answer 0x${vote}`;
}
};
Loading