Skip to content

Commit f7b6240

Browse files
committed
Merge branch 'dev' into feat(web)/dispute-template-view-improvements
2 parents b41e91b + 6fc7588 commit f7b6240

File tree

10 files changed

+56
-93
lines changed

10 files changed

+56
-93
lines changed

web/src/components/DisputeCard/index.tsx

+5-14
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,11 @@ import { useIsList } from "context/IsListProvider";
99
import { DisputeDetailsFragment } from "queries/useCasesQuery";
1010
import { landscapeStyle } from "styles/landscapeStyle";
1111
import { useCourtPolicy } from "queries/useCourtPolicy";
12-
import { useDisputeTemplate } from "queries/useDisputeTemplate";
12+
import { usePopulatedDisputeData } from "hooks/queries/usePopulatedDisputeData";
1313
import DisputeInfo from "./DisputeInfo";
1414
import PeriodBanner from "./PeriodBanner";
1515
import { isUndefined } from "utils/index";
1616
import { responsiveSize } from "styles/responsiveSize";
17-
import { populateTemplate } from "@kleros/kleros-sdk/src/dataMappings/utils/populateTemplate";
18-
import { DisputeDetails } from "@kleros/kleros-sdk/src/dataMappings/utils/disputeDetailsTypes";
1917
import { INVALID_DISPUTE_DATA_ERROR } from "consts/index";
2018

2119
const StyledCard = styled(Card)`
@@ -106,26 +104,19 @@ const DisputeCard: React.FC<IDisputeCard> = ({
106104
currentPeriodIndex === 4
107105
? lastPeriodChange
108106
: getPeriodEndTimestamp(lastPeriodChange, currentPeriodIndex, court.timesPerPeriod);
109-
const { data: disputeTemplate } = useDisputeTemplate(id, arbitrated.id as `0x${string}`);
110-
let disputeDetails: DisputeDetails | undefined;
111-
try {
112-
if (disputeTemplate) {
113-
disputeDetails = populateTemplate(disputeTemplate.templateData, {});
114-
}
115-
} catch (e) {
116-
console.error(e);
117-
}
107+
const { data: disputeDetails } = usePopulatedDisputeData(id, arbitrated.id as `0x${string}`);
108+
118109
const { data: courtPolicy } = useCourtPolicy(court.id);
119110
const courtName = courtPolicy?.name;
120-
const category = disputeTemplate?.category;
111+
const category = disputeDetails?.category;
121112
const navigate = useNavigate();
122113
return (
123114
<>
124115
{!isList || overrideIsList ? (
125116
<StyledCard hover onClick={() => navigate(`/cases/${id.toString()}`)}>
126117
<PeriodBanner id={parseInt(id)} period={currentPeriodIndex} />
127118
<CardContainer>
128-
{isUndefined(disputeTemplate) ? (
119+
{isUndefined(disputeDetails) ? (
129120
<StyledSkeleton />
130121
) : (
131122
<TruncatedTitle text={disputeDetails?.title ?? INVALID_DISPUTE_DATA_ERROR} maxLength={100} />

web/src/components/DisputePreview/DisputeContext.tsx

+2-5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { Answer as IAnswer } from "context/NewDisputeContext";
77
import AliasDisplay from "./Alias";
88
import { responsiveSize } from "styles/responsiveSize";
99
import { DisputeDetails } from "@kleros/kleros-sdk/src/dataMappings/utils/disputeDetailsTypes";
10+
import { INVALID_DISPUTE_DATA_ERROR } from "consts/index";
1011

1112
const StyledH1 = styled.h1`
1213
margin: 0;
@@ -65,11 +66,7 @@ export const DisputeContext: React.FC<IDisputeContext> = ({ disputeDetails }) =>
6566
return (
6667
<>
6768
<StyledH1>
68-
{isUndefined(disputeDetails) ? (
69-
<StyledSkeleton />
70-
) : (
71-
disputeDetails?.title ?? "The dispute's template is not correct please vote refuse to arbitrate"
72-
)}
69+
{isUndefined(disputeDetails) ? <StyledSkeleton /> : disputeDetails?.title ?? INVALID_DISPUTE_DATA_ERROR}
7370
</StyledH1>
7471
{!isUndefined(disputeDetails) && (
7572
<QuestionAndDescription>

web/src/components/Verdict/DisputeTimeline.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import AppealedCaseIcon from "assets/svgs/icons/close-circle.svg";
88
import { Periods } from "consts/periods";
99
import { ClassicRound } from "src/graphql/graphql";
1010
import { DisputeDetailsQuery, useDisputeDetailsQuery } from "queries/useDisputeDetailsQuery";
11-
import { useDisputeTemplate } from "queries/useDisputeTemplate";
11+
import { usePopulatedDisputeData } from "hooks/queries/usePopulatedDisputeData";
1212
import { useVotingHistory } from "queries/useVotingHistory";
1313
import { getLocalRounds } from "utils/getLocalRounds";
1414
import { responsiveSize } from "styles/responsiveSize";
@@ -56,7 +56,7 @@ type TimelineItems = [_TimelineItem1, ..._TimelineItem1[]];
5656
const useItems = (disputeDetails?: DisputeDetailsQuery, arbitrable?: `0x${string}`) => {
5757
const { id } = useParams();
5858
const { data: votingHistory } = useVotingHistory(id);
59-
const { data: disputeTemplate } = useDisputeTemplate(id, arbitrable);
59+
const { data: disputeData } = usePopulatedDisputeData(id, arbitrable);
6060
const localRounds: ClassicRound[] = getLocalRounds(votingHistory?.dispute?.disputeKitDispute) as ClassicRound[];
6161
const rounds = votingHistory?.dispute?.rounds;
6262
const theme = useTheme();
@@ -75,7 +75,7 @@ const useItems = (disputeDetails?: DisputeDetailsQuery, arbitrable?: `0x${string
7575
const roundTimeline = rounds?.[index].timeline;
7676

7777
const icon = dispute.ruled && !rulingOverride && index === localRounds.length - 1 ? ClosedCaseIcon : "";
78-
const answers = disputeTemplate?.answers;
78+
const answers = disputeData?.answers;
7979
acc.push({
8080
title: `Jury Decision - Round ${index + 1}`,
8181
party: isOngoing ? "Voting is ongoing" : getVoteChoice(parsedRoundChoice, answers),
@@ -121,7 +121,7 @@ const useItems = (disputeDetails?: DisputeDetailsQuery, arbitrable?: `0x${string
121121
);
122122
}
123123
return;
124-
}, [disputeDetails, disputeTemplate, localRounds, theme]);
124+
}, [disputeDetails, disputeData, localRounds, theme]);
125125
};
126126

127127
interface IDisputeTimeline {

web/src/components/Verdict/FinalDecision.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import styled from "styled-components";
44
import ArrowIcon from "assets/svgs/icons/arrow.svg";
55
import { useKlerosCoreCurrentRuling } from "hooks/contracts/generated";
66
import { useDisputeDetailsQuery } from "queries/useDisputeDetailsQuery";
7-
import { useDisputeTemplate } from "queries/useDisputeTemplate";
7+
import { usePopulatedDisputeData } from "hooks/queries/usePopulatedDisputeData";
88
import LightButton from "../LightButton";
99
import VerdictBanner from "./VerdictBanner";
1010
import { responsiveSize } from "styles/responsiveSize";
@@ -61,14 +61,14 @@ interface IFinalDecision {
6161
const FinalDecision: React.FC<IFinalDecision> = ({ arbitrable }) => {
6262
const { id } = useParams();
6363
const { isDisconnected } = useAccount();
64-
const { data: disputeTemplate } = useDisputeTemplate(id, arbitrable);
64+
const { data: populatedDisputeData } = usePopulatedDisputeData(id, arbitrable);
6565
const { data: disputeDetails } = useDisputeDetailsQuery(id);
6666
const { wasDrawn, hasVoted, isLoading, isCommitPeriod, isVotingPeriod, commited, isHiddenVotes } = useVotingContext();
6767
const ruled = disputeDetails?.dispute?.ruled ?? false;
6868
const navigate = useNavigate();
6969
const { data: currentRulingArray } = useKlerosCoreCurrentRuling({ args: [BigInt(id ?? 0)], watch: true });
7070
const currentRuling = Number(currentRulingArray?.[0]);
71-
const answer = disputeTemplate?.answers?.[currentRuling! - 1];
71+
const answer = populatedDisputeData?.answers?.[currentRuling! - 1];
7272
const buttonText = useMemo(() => {
7373
if (!wasDrawn || isDisconnected) return "Check how the jury voted";
7474
if (isCommitPeriod && !commited) return "Commit your vote";

web/src/hooks/queries/useDisputeTemplate.ts web/src/hooks/queries/usePopulatedDisputeData.ts

+20-7
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@ import { PublicClient } from "viem";
44
import { usePublicClient } from "wagmi";
55
import { getIArbitrableV2 } from "hooks/contracts/generated";
66
import { isUndefined } from "utils/index";
7-
import { graphqlQueryFnHelper, graphqlUrl } from "utils/graphqlQueryFnHelper";
7+
import { graphqlQueryFnHelper } from "utils/graphqlQueryFnHelper";
88
import { useIsCrossChainDispute } from "../useIsCrossChainDispute";
99
import { GENESIS_BLOCK_ARBSEPOLIA } from "consts/index";
10+
import { populateTemplate } from "@kleros/kleros-sdk/src/dataMappings/utils/populateTemplate";
11+
import { executeActions } from "@kleros/kleros-sdk/src/dataMappings/executeActions";
12+
import { DisputeDetails } from "@kleros/kleros-sdk/src/dataMappings/utils/disputeDetailsTypes";
1013

1114
const disputeTemplateQuery = graphql(`
1215
query DisputeTemplate($id: ID!) {
@@ -19,31 +22,41 @@ const disputeTemplateQuery = graphql(`
1922
}
2023
`);
2124

22-
export const useDisputeTemplate = (disputeID?: string, arbitrableAddress?: `0x${string}`) => {
25+
export const usePopulatedDisputeData = (disputeID?: string, arbitrableAddress?: `0x${string}`) => {
2326
const publicClient = usePublicClient();
2427
const { data: crossChainData } = useIsCrossChainDispute(disputeID, arbitrableAddress);
2528
const isEnabled = !isUndefined(disputeID) && !isUndefined(crossChainData) && !isUndefined(arbitrableAddress);
26-
return useQuery({
29+
return useQuery<DisputeDetails>({
2730
queryKey: [`DisputeTemplate${disputeID}${arbitrableAddress}`],
2831
enabled: isEnabled,
2932
staleTime: Infinity,
3033
queryFn: async () => {
3134
if (isEnabled) {
3235
try {
33-
const { isCrossChainDispute, crossChainId, crossChainTemplateId } = crossChainData;
36+
const { isCrossChainDispute, crossChainTemplateId } = crossChainData;
3437
const templateId = isCrossChainDispute
3538
? crossChainTemplateId
3639
: await getTemplateId(arbitrableAddress, disputeID, publicClient);
40+
3741
const { disputeTemplate } = await graphqlQueryFnHelper(
3842
disputeTemplateQuery,
3943
{ id: templateId.toString() },
4044
true
4145
);
42-
console.log("useDisputeTemplate:", disputeTemplate);
46+
const templateData = disputeTemplate?.templateData;
47+
const dataMappings = disputeTemplate?.templateDataMappings;
48+
49+
const initialContext = {
50+
disputeID: disputeID,
51+
arbitrable: arbitrableAddress,
52+
};
53+
54+
const data = dataMappings ? await executeActions(JSON.parse(dataMappings), initialContext) : {};
55+
const disputeDetails = populateTemplate(templateData, data);
4356

44-
return disputeTemplate;
57+
return disputeDetails;
4558
} catch {
46-
return {};
59+
return {} as DisputeDetails;
4760
}
4861
} else throw Error;
4962
},

web/src/hooks/useClassicAppealContext.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React, { useMemo, useState, createContext, useContext } from "react";
22
import { useParams } from "react-router-dom";
33
import { ONE_BASIS_POINT } from "consts/index";
44
import { Periods } from "consts/periods";
5-
import { useDisputeTemplate } from "queries/useDisputeTemplate";
5+
import { usePopulatedDisputeData } from "hooks/queries/usePopulatedDisputeData";
66
import { useAppealCost } from "queries/useAppealCost";
77
import { useDisputeKitClassicMultipliers } from "queries/useDisputeKitClassicMultipliers";
88
import { useClassicAppealQuery, ClassicAppealQuery } from "queries/useClassicAppealQuery";
@@ -52,10 +52,10 @@ export const ClassicAppealProvider: React.FC<{
5252
const winningChoice = getWinningChoice(data?.dispute);
5353
const { data: appealCost } = useAppealCost(id);
5454
const arbitrable = data?.dispute?.arbitrated.id;
55-
const { data: disputeTemplate } = useDisputeTemplate(id, arbitrable);
55+
const { data: disputeDetails } = usePopulatedDisputeData(id, arbitrable);
5656
const { data: multipliers } = useDisputeKitClassicMultipliers();
5757
const options = ["Refuse to Arbitrate"].concat(
58-
disputeTemplate?.answers?.map((answer: { title: string; description: string }) => {
58+
disputeDetails?.answers?.map((answer: { title: string; description: string }) => {
5959
return answer.title;
6060
})
6161
);

web/src/pages/Cases/CaseDetails/Overview/index.tsx

+4-42
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,10 @@
1-
import React, { useMemo, useState, useEffect } from "react";
1+
import React, { useMemo } from "react";
22
import styled from "styled-components";
33
import { useParams } from "react-router-dom";
44
import { formatEther } from "viem";
55
import { useDisputeDetailsQuery } from "queries/useDisputeDetailsQuery";
6-
import { useDisputeTemplate } from "queries/useDisputeTemplate";
6+
import { usePopulatedDisputeData } from "hooks/queries/usePopulatedDisputeData";
77
import { useCourtPolicy } from "queries/useCourtPolicy";
8-
import { populateTemplate } from "@kleros/kleros-sdk/src/dataMappings/utils/populateTemplate";
9-
import { executeActions } from "@kleros/kleros-sdk/src/dataMappings/executeActions";
10-
import { configureSDK } from "@kleros/kleros-sdk/src/sdk";
11-
import { alchemyApiKey } from "context/Web3Provider";
12-
import { DisputeDetails } from "@kleros/kleros-sdk/src/dataMappings/utils/disputeDetailsTypes";
138
import DisputeInfo from "components/DisputeCard/DisputeInfo";
149
import Verdict from "components/Verdict/index";
1510
import { useVotingHistory } from "hooks/queries/useVotingHistory";
@@ -44,48 +39,15 @@ interface IOverview {
4439

4540
const Overview: React.FC<IOverview> = ({ arbitrable, courtID, currentPeriodIndex }) => {
4641
const { id } = useParams();
47-
const { data: disputeTemplate } = useDisputeTemplate(id, arbitrable);
42+
const { data: disputeDetails } = usePopulatedDisputeData(id, arbitrable);
4843
const { data: dispute } = useDisputeDetailsQuery(id);
4944
const { data: courtPolicy } = useCourtPolicy(courtID);
5045
const { data: votingHistory } = useVotingHistory(id);
51-
const [disputeDetails, setDisputeDetails] = useState<DisputeDetails | undefined>(undefined);
5246
const localRounds = getLocalRounds(votingHistory?.dispute?.disputeKitDispute);
5347
const courtName = courtPolicy?.name;
5448
const court = dispute?.dispute?.court;
5549
const rewards = useMemo(() => (court ? `≥ ${formatEther(court.feeForJuror)} ETH` : undefined), [court]);
56-
const category = disputeTemplate?.category ?? undefined;
57-
const disputeTemplateInput = disputeTemplate?.templateData;
58-
const dataMappingsInput = disputeTemplate?.templateDataMappings;
59-
60-
useEffect(() => {
61-
configureSDK({ apiKey: alchemyApiKey });
62-
const initialContext = {
63-
disputeID: id,
64-
arbitrable: arbitrable,
65-
};
66-
67-
if (!disputeTemplateInput) return;
68-
69-
const fetchData = async () => {
70-
try {
71-
console.log("dataMappingsInput", dataMappingsInput);
72-
let data = {};
73-
if (dataMappingsInput) {
74-
const parsedMappings = JSON.parse(dataMappingsInput);
75-
console.log("parsedMappings", parsedMappings);
76-
data = await executeActions(parsedMappings, initialContext);
77-
}
78-
console.log("data", data);
79-
const finalDisputeDetails = populateTemplate(disputeTemplateInput, data);
80-
setDisputeDetails(finalDisputeDetails);
81-
} catch (e) {
82-
console.error(e);
83-
setDisputeDetails(undefined);
84-
}
85-
};
86-
87-
fetchData();
88-
}, [disputeTemplateInput, dataMappingsInput, arbitrable, id]);
50+
const category = disputeDetails?.category;
8951

9052
return (
9153
<>

web/src/pages/Cases/CaseDetails/Voting/Classic/OptionsContainer.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { useParams } from "react-router-dom";
44
import ReactMarkdown from "react-markdown";
55
import { Button } from "@kleros/ui-components-library";
66
import { isUndefined } from "utils/index";
7-
import { useDisputeTemplate } from "queries/useDisputeTemplate";
7+
import { usePopulatedDisputeData } from "hooks/queries/usePopulatedDisputeData";
88
import { EnsureChain } from "components/EnsureChain";
99
import JustificationArea from "./JustificationArea";
1010

@@ -43,7 +43,7 @@ interface IOptions {
4343

4444
const Options: React.FC<IOptions> = ({ arbitrable, handleSelection, justification, setJustification }) => {
4545
const { id } = useParams();
46-
const { data: disputeTemplate } = useDisputeTemplate(id, arbitrable);
46+
const { data: disputeDetails } = usePopulatedDisputeData(id, arbitrable);
4747
const [chosenOption, setChosenOption] = useState(-1);
4848
const [isSending, setIsSending] = useState(false);
4949

@@ -61,12 +61,12 @@ const Options: React.FC<IOptions> = ({ arbitrable, handleSelection, justificatio
6161
return id ? (
6262
<>
6363
<MainContainer>
64-
<ReactMarkdown>{disputeTemplate?.question}</ReactMarkdown>
64+
<ReactMarkdown>{disputeDetails?.question}</ReactMarkdown>
6565
{!isUndefined(justification) && !isUndefined(setJustification) ? (
6666
<JustificationArea {...{ justification, setJustification }} />
6767
) : null}
6868
<OptionsContainer>
69-
{disputeTemplate?.answers?.map((answer: { title: string; description: string }, i: number) => {
69+
{disputeDetails?.answers?.map((answer: { title: string; description: string }, i: number) => {
7070
return (
7171
<EnsureChain key={answer.title}>
7272
<Button

web/src/pages/Cases/CaseDetails/Voting/Classic/Reveal.tsx

+5-5
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { Button } from "@kleros/ui-components-library";
99
import { prepareWriteDisputeKitClassic } from "hooks/contracts/generated";
1010
import useSigningAccount from "hooks/useSigningAccount";
1111
import { useDisputeDetailsQuery } from "queries/useDisputeDetailsQuery";
12-
import { useDisputeTemplate } from "queries/useDisputeTemplate";
12+
import { usePopulatedDisputeData } from "hooks/queries/usePopulatedDisputeData";
1313
import { isUndefined } from "utils/index";
1414
import { wrapWithToast, catchShortMessage } from "utils/wrapWithToast";
1515
import InfoCard from "components/InfoCard";
@@ -43,7 +43,7 @@ const Reveal: React.FC<IReveal> = ({ arbitrable, voteIDs, setIsOpen, commit, isR
4343
const parsedVoteIDs = useMemo(() => voteIDs.map((voteID) => BigInt(voteID)), [voteIDs]);
4444
const { data: disputeData } = useDisputeDetailsQuery(id);
4545
const [justification, setJustification] = useState("");
46-
const { data: disputeTemplate } = useDisputeTemplate(id, arbitrable);
46+
const { data: disputeDetails } = usePopulatedDisputeData(id, arbitrable);
4747
const { data: walletClient } = useWalletClient();
4848
const publicClient = usePublicClient();
4949
const { signingAccount, generateSigningAccount } = useSigningAccount();
@@ -57,7 +57,7 @@ const Reveal: React.FC<IReveal> = ({ arbitrable, voteIDs, setIsOpen, commit, isR
5757
const handleReveal = useCallback(async () => {
5858
setIsSending(true);
5959
const { salt, choice } = isUndefined(storedSaltAndChoice)
60-
? await getSaltAndChoice(signingAccount, generateSigningAccount, saltKey, disputeTemplate.answers, commit)
60+
? await getSaltAndChoice(signingAccount, generateSigningAccount, saltKey, disputeDetails.answers, commit)
6161
: JSON.parse(storedSaltAndChoice);
6262
if (isUndefined(choice)) return;
6363
const { request } = await catchShortMessage(
@@ -74,7 +74,7 @@ const Reveal: React.FC<IReveal> = ({ arbitrable, voteIDs, setIsOpen, commit, isR
7474
setIsSending(false);
7575
}, [
7676
commit,
77-
disputeTemplate?.answers,
77+
disputeDetails?.answers,
7878
storedSaltAndChoice,
7979
generateSigningAccount,
8080
signingAccount,
@@ -93,7 +93,7 @@ const Reveal: React.FC<IReveal> = ({ arbitrable, voteIDs, setIsOpen, commit, isR
9393
<StyledInfoCard msg="Failed to commit on time." />
9494
) : isRevealPeriod ? (
9595
<>
96-
<ReactMarkdown>{disputeTemplate?.question}</ReactMarkdown>
96+
<ReactMarkdown>{disputeDetails?.question}</ReactMarkdown>
9797
<JustificationArea {...{ justification, setJustification }} />
9898
<StyledButton
9999
variant="secondary"

0 commit comments

Comments
 (0)