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/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/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/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..5d6274388 100644 --- a/web/src/pages/Resolver/Parameters/Court.tsx +++ b/web/src/pages/Resolver/Parameters/Court.tsx @@ -1,10 +1,12 @@ 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"; +import { useSupportedDisputeKits } from "queries/useSupportedDisputeKits"; +import { getDisputeKitName } from "consts/index"; import { isUndefined } from "utils/index"; import { landscapeStyle } from "styles/landscapeStyle"; @@ -49,28 +51,52 @@ 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 { data: courtTree } = useCourtTree(); + const { data: supportedDisputeKits } = useSupportedDisputeKits(disputeData.courtId); + const items = useMemo(() => !isUndefined(courtTree?.court) && [rootCourtToItems(courtTree.court)], [courtTree]); + const disputeKitOptions = useMemo(() => { + const supportedDisputeKitIDs = supportedDisputeKits?.court?.supportedDisputeKits.map((k) => Number(k.id)) || []; + return supportedDisputeKitIDs.map((id) => ({ text: getDisputeKitName(id), value: id })); + }, [supportedDisputeKits]); + const handleCourtWrite = (courtId: string) => { + setDisputeData({ ...disputeData, courtId, disputeKitId: undefined }); }; + 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;