From fc3d4ca670f35640e770b29f47d861c40d52ad97 Mon Sep 17 00:00:00 2001 From: kemuru <102478601+kemuru@users.noreply.github.com> Date: Tue, 13 May 2025 04:49:11 +0200 Subject: [PATCH 1/2] feat: allow choosing the disputekit in the resolver flow --- web/src/context/NewDisputeContext.tsx | 4 +- .../NavigationButtons/SubmitDisputeButton.tsx | 7 +++- web/src/pages/Resolver/Parameters/Court.tsx | 38 +++++++++++++++++-- 3 files changed, 42 insertions(+), 7 deletions(-) diff --git a/web/src/context/NewDisputeContext.tsx b/web/src/context/NewDisputeContext.tsx index f15e2440b..ccfdd9e9c 100644 --- a/web/src/context/NewDisputeContext.tsx +++ b/web/src/context/NewDisputeContext.tsx @@ -47,6 +47,7 @@ interface IDisputeData extends IDisputeTemplate { numberOfJurors: number; arbitrationCost?: string; aliasesArray?: AliasArray[]; + disputeKitId?: number; } interface INewDisputeContext { @@ -71,6 +72,7 @@ const getInitialDisputeData = (): IDisputeData => ({ { title: "", id: "2", description: "" }, ], aliasesArray: [{ name: "", address: "", id: "1" }], + disputeKitId: 1, version: "1.0", }); @@ -117,7 +119,7 @@ export const NewDisputeProvider: React.FC<{ children: React.ReactNode }> = ({ ch const constructDisputeTemplate = (disputeData: IDisputeData) => { // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { courtId, numberOfJurors, arbitrationCost, ...baseTemplate } = disputeData; + const { courtId, numberOfJurors, arbitrationCost, disputeKitId, ...baseTemplate } = disputeData; if (!isUndefined(baseTemplate.aliasesArray)) { baseTemplate.aliasesArray = baseTemplate.aliasesArray.filter((item) => item.address !== "" && item.isValid); diff --git a/web/src/pages/Resolver/NavigationButtons/SubmitDisputeButton.tsx b/web/src/pages/Resolver/NavigationButtons/SubmitDisputeButton.tsx index 5db0a357f..f2ad186b4 100644 --- a/web/src/pages/Resolver/NavigationButtons/SubmitDisputeButton.tsx +++ b/web/src/pages/Resolver/NavigationButtons/SubmitDisputeButton.tsx @@ -42,13 +42,16 @@ const SubmitDisputeButton: React.FC = () => { return userBalance && userBalance.value < arbitrationCost; }, [userBalance, disputeData]); - // TODO: decide which dispute kit to use const { data: submitCaseConfig, error } = useSimulateDisputeResolverCreateDisputeForTemplate({ query: { enabled: !insufficientBalance && isTemplateValid(disputeTemplate), }, args: [ - prepareArbitratorExtradata(disputeData.courtId ?? "1", disputeData.numberOfJurors ?? "", 1), + prepareArbitratorExtradata( + disputeData.courtId ?? "1", + disputeData.numberOfJurors ?? "", + disputeData.disputeKitId ?? 1 + ), JSON.stringify(disputeTemplate), "", BigInt(disputeTemplate.answers.length), diff --git a/web/src/pages/Resolver/Parameters/Court.tsx b/web/src/pages/Resolver/Parameters/Court.tsx index c9b3b568d..1bad50ec0 100644 --- a/web/src/pages/Resolver/Parameters/Court.tsx +++ b/web/src/pages/Resolver/Parameters/Court.tsx @@ -1,7 +1,7 @@ import React, { useMemo } from "react"; import styled, { css } from "styled-components"; -import { AlertMessage, DropdownCascader } from "@kleros/ui-components-library"; +import { AlertMessage, DropdownCascader, DropdownSelect } from "@kleros/ui-components-library"; import { useNewDisputeContext } from "context/NewDisputeContext"; import { rootCourtToItems, useCourtTree } from "hooks/queries/useCourtTree"; @@ -14,6 +14,7 @@ import { StyledSkeleton } from "components/StyledSkeleton"; import Header from "pages/Resolver/Header"; import NavigationButtons from "../NavigationButtons"; +import { isKlerosNeo, isKlerosUniversity, isTestnetDeployment } from "src/consts"; const Container = styled.div` display: flex; @@ -49,28 +50,56 @@ const AlertMessageContainer = styled.div` margin-top: 24px; `; +const StyledDropdownSelect = styled(DropdownSelect)` + width: 84vw; + margin-top: 24px; + ${landscapeStyle( + () => css` + width: ${responsiveSize(442, 700, 900)}; + ` + )} +`; + const Court: React.FC = () => { const { disputeData, setDisputeData } = useNewDisputeContext(); const { data } = useCourtTree(); const items = useMemo(() => !isUndefined(data?.court) && [rootCourtToItems(data.court)], [data]); - const handleWrite = (courtId: string) => { - setDisputeData({ ...disputeData, courtId: courtId }); + const disputeKitOptions = useMemo(() => { + if (isKlerosUniversity()) return [{ text: "Classic Dispute Kit", value: 1 }]; + if (isKlerosNeo()) return [{ text: "Classic Dispute Kit", value: 1 }]; + if (isTestnetDeployment()) return [{ text: "Classic Dispute Kit", value: 1 }]; + const options = [{ text: "Classic Dispute Kit", value: 1 }]; + if (disputeData.courtId === "1") options.push({ text: "Shutter Dispute Kit", value: 2 }); + return options; + }, [disputeData.courtId]); + + const handleCourtWrite = (courtId: string) => { + const newDisputeKitId = courtId === "1" ? (disputeData.disputeKitId ?? 1) : 1; + setDisputeData({ ...disputeData, courtId, disputeKitId: newDisputeKitId }); }; + const handleDisputeKitChange = (newValue: string | number) => + setDisputeData({ ...disputeData, disputeKitId: Number(newValue) }); + return (
{items ? ( typeof path === "string" && handleWrite(path.split("/").pop()!)} + onSelect={(path: string | number) => typeof path === "string" && handleCourtWrite(path.split("/").pop()!)} placeholder="Select Court" value={`/courts/${disputeData.courtId}`} /> ) : ( )} + { ); }; + export default Court; From 0c96fa268abbccd26c9c6ba3cdce401e45d0d1ff Mon Sep 17 00:00:00 2001 From: kemuru <102478601+kemuru@users.noreply.github.com> Date: Tue, 13 May 2025 18:46:39 +0200 Subject: [PATCH 2/2] chore: improvement in disputekitid fetching and showing --- web/src/consts/index.ts | 12 ++++++++ .../hooks/queries/useSupportedDisputeKits.ts | 29 +++++++++++++++++++ web/src/pages/Resolver/Parameters/Court.tsx | 27 ++++++++--------- 3 files changed, 53 insertions(+), 15 deletions(-) create mode 100644 web/src/hooks/queries/useSupportedDisputeKits.ts diff --git a/web/src/consts/index.ts b/web/src/consts/index.ts index 219ff0e9c..0064f4a98 100644 --- a/web/src/consts/index.ts +++ b/web/src/consts/index.ts @@ -42,3 +42,15 @@ export const INVALID_DISPUTE_DATA_ERROR = `The dispute data is not valid, please export const RPC_ERROR = `RPC Error: Unable to fetch dispute data. Please avoid voting.`; export const spamEvidencesIds: string[] = (import.meta.env.REACT_APP_SPAM_EVIDENCES_IDS ?? "").split(","); + +export const getDisputeKitName = (id: number): string | undefined => { + const universityDisputeKits: Record = { 1: "Classic Dispute Kit" }; + const neoDisputeKits: Record = { 1: "Classic Dispute Kit" }; + const testnetDisputeKits: Record = { 1: "Classic Dispute Kit" }; + const devnetDisputeKits: Record = { 1: "Classic Dispute Kit", 2: "Shutter Dispute Kit" }; + + if (isKlerosUniversity()) return universityDisputeKits[id]; + if (isKlerosNeo()) return neoDisputeKits[id]; + if (isTestnetDeployment()) return testnetDisputeKits[id]; + return devnetDisputeKits[id]; +}; diff --git a/web/src/hooks/queries/useSupportedDisputeKits.ts b/web/src/hooks/queries/useSupportedDisputeKits.ts new file mode 100644 index 000000000..d8aed6603 --- /dev/null +++ b/web/src/hooks/queries/useSupportedDisputeKits.ts @@ -0,0 +1,29 @@ +import { useQuery } from "@tanstack/react-query"; +import { useGraphqlBatcher } from "context/GraphqlBatcher"; +import { graphql } from "src/graphql"; +import { SupportedDisputeKitsQuery } from "src/graphql/graphql"; + +const supportedDisputeKitsQuery = graphql(` + query SupportedDisputeKits($id: ID!) { + court(id: $id) { + supportedDisputeKits { + id + } + } + } +`); + +export const useSupportedDisputeKits = (courtId?: string) => { + const { graphqlBatcher } = useGraphqlBatcher(); + return useQuery({ + enabled: !!courtId, + queryKey: ["SupportedDisputeKits", courtId], + staleTime: Infinity, + queryFn: async () => + await graphqlBatcher.fetch({ + id: crypto.randomUUID(), + document: supportedDisputeKitsQuery, + variables: { id: courtId }, + }), + }); +}; diff --git a/web/src/pages/Resolver/Parameters/Court.tsx b/web/src/pages/Resolver/Parameters/Court.tsx index 1bad50ec0..5d6274388 100644 --- a/web/src/pages/Resolver/Parameters/Court.tsx +++ b/web/src/pages/Resolver/Parameters/Court.tsx @@ -5,6 +5,8 @@ import { AlertMessage, DropdownCascader, DropdownSelect } from "@kleros/ui-compo import { useNewDisputeContext } from "context/NewDisputeContext"; import { rootCourtToItems, useCourtTree } from "hooks/queries/useCourtTree"; +import { useSupportedDisputeKits } from "queries/useSupportedDisputeKits"; +import { getDisputeKitName } from "consts/index"; import { isUndefined } from "utils/index"; import { landscapeStyle } from "styles/landscapeStyle"; @@ -14,7 +16,6 @@ import { StyledSkeleton } from "components/StyledSkeleton"; import Header from "pages/Resolver/Header"; import NavigationButtons from "../NavigationButtons"; -import { isKlerosNeo, isKlerosUniversity, isTestnetDeployment } from "src/consts"; const Container = styled.div` display: flex; @@ -62,21 +63,15 @@ const StyledDropdownSelect = styled(DropdownSelect)` const Court: React.FC = () => { const { disputeData, setDisputeData } = useNewDisputeContext(); - const { data } = useCourtTree(); - const items = useMemo(() => !isUndefined(data?.court) && [rootCourtToItems(data.court)], [data]); - + const { data: courtTree } = useCourtTree(); + const { data: supportedDisputeKits } = useSupportedDisputeKits(disputeData.courtId); + const items = useMemo(() => !isUndefined(courtTree?.court) && [rootCourtToItems(courtTree.court)], [courtTree]); const disputeKitOptions = useMemo(() => { - if (isKlerosUniversity()) return [{ text: "Classic Dispute Kit", value: 1 }]; - if (isKlerosNeo()) return [{ text: "Classic Dispute Kit", value: 1 }]; - if (isTestnetDeployment()) return [{ text: "Classic Dispute Kit", value: 1 }]; - const options = [{ text: "Classic Dispute Kit", value: 1 }]; - if (disputeData.courtId === "1") options.push({ text: "Shutter Dispute Kit", value: 2 }); - return options; - }, [disputeData.courtId]); - + const supportedDisputeKitIDs = supportedDisputeKits?.court?.supportedDisputeKits.map((k) => Number(k.id)) || []; + return supportedDisputeKitIDs.map((id) => ({ text: getDisputeKitName(id), value: id })); + }, [supportedDisputeKits]); const handleCourtWrite = (courtId: string) => { - const newDisputeKitId = courtId === "1" ? (disputeData.disputeKitId ?? 1) : 1; - setDisputeData({ ...disputeData, courtId, disputeKitId: newDisputeKitId }); + setDisputeData({ ...disputeData, courtId, disputeKitId: undefined }); }; const handleDisputeKitChange = (newValue: string | number) => @@ -96,8 +91,10 @@ const Court: React.FC = () => { )}