Skip to content

Commit 912e03a

Browse files
committed
Merge branch 'feat/devtools' into feat(devtools)/initial-setup-for-devtool-website
2 parents f3a311c + 4a1ae9e commit 912e03a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1020
-211
lines changed

kleros-sdk/src/dataMappings/actions/jsonAction.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ import { JsonMapping } from "../utils/actionTypes";
22
import { createResultObject } from "src/dataMappings/utils/createResultObject";
33

44
export const jsonAction = (mapping: JsonMapping) => {
5-
const { value: source, seek, populate } = mapping;
6-
return createResultObject(source, seek, populate);
5+
const { value, seek, populate } = mapping;
6+
7+
// Parse the source if it's a JSON string
8+
const parsedValue = typeof value === "string" ? JSON.parse(value) : value;
9+
10+
return createResultObject(parsedValue, seek, populate);
711
};

kleros-sdk/src/dataMappings/executeActions.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ export const executeActions = async (mappings, initialContext = {}) => {
4242

4343
for (const mapping of mappings) {
4444
const actionResult = await executeAction(mapping, context);
45+
4546
if (actionResult) {
4647
Object.keys(actionResult).forEach((key) => {
4748
context[key] = actionResult[key];
Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,22 @@
1-
// Can this be replaced by Mustache ?
2-
export const createResultObject = (sourceData, seek, populate) => {
1+
export const createResultObject = (sourceData, seek: string[], populate: string[]) => {
32
const result = {};
43

5-
seek.forEach((key, idx) => {
6-
let foundValue = sourceData;
7-
8-
if (key.includes(".")) {
9-
const keyParts = key.split(".");
10-
for (const part of keyParts) {
11-
if (foundValue[part] !== undefined) {
12-
foundValue = foundValue[part];
13-
} else {
14-
foundValue = undefined;
15-
break;
16-
}
17-
}
18-
} else {
19-
if (typeof sourceData !== "object" || key === "0") {
20-
foundValue = sourceData;
21-
} else {
22-
foundValue = sourceData[key];
4+
const getNestedValue = (obj: any, path: string) => {
5+
return path.split(".").reduce((acc, part) => {
6+
if (acc && part.includes("[")) {
7+
const [key, index] = part.replace(/\]/g, "").split("[");
8+
return acc[key]?.[index];
239
}
24-
}
10+
return acc ? acc[part] : undefined;
11+
}, obj);
12+
};
2513

26-
console.log(`Seek key: ${key}, Found value:`, foundValue);
14+
seek.forEach((key, idx) => {
15+
const foundValue = getNestedValue(sourceData, key);
2716
if (foundValue !== undefined) {
2817
result[populate[idx]] = foundValue;
29-
console.log(`Populate key: ${populate[idx]}, Value to add:`, foundValue);
3018
}
3119
});
32-
console.log("Result object:", result);
20+
3321
return result;
3422
};

kleros-sdk/src/dataMappings/utils/populateTemplate.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { validate } from "./DisputeDetailsValidator";
44

55
export const populateTemplate = (mustacheTemplate: string, data: any): DisputeDetails => {
66
const render = mustache.render(mustacheTemplate, data);
7-
console.log("MUSTACHE RENDER: ", render);
87
const dispute = JSON.parse(render);
98

109
// TODO: the validation below is too strict, it should be fixed, disabled for now, FIXME
Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
1-
export const replacePlaceholdersWithValues = (mapping: any, context: any) => {
2-
let mappingAsString = JSON.stringify(mapping);
1+
import mustache from "mustache";
32

4-
const replacedMapping = mappingAsString.replace(/\{\{(\w+)\}\}/g, (_, variableName) => {
5-
if (context.hasOwnProperty(variableName)) {
6-
return context[variableName];
3+
export const replacePlaceholdersWithValues = (mapping: any, context: any) => {
4+
const replace = (obj) => {
5+
if (typeof obj === "string") {
6+
return mustache.render(obj, context);
7+
} else if (Array.isArray(obj)) {
8+
return obj.map(replace);
9+
} else if (typeof obj === "object" && obj !== null) {
10+
return Object.fromEntries(Object.entries(obj).map(([key, value]) => [key, replace(value)]));
711
} else {
8-
throw new Error(`Variable '${variableName}' not found in context.`);
12+
return obj;
913
}
10-
});
14+
};
1115

12-
return JSON.parse(replacedMapping);
16+
return replace(mapping);
1317
};

subgraph/core/schema.graphql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ interface Evidence {
5353
evidence: String!
5454
evidenceGroup: EvidenceGroup!
5555
sender: User!
56+
timestamp: BigInt!
5657
}
5758

5859
############
@@ -296,6 +297,7 @@ type ClassicEvidence implements Evidence @entity {
296297
evidence: String!
297298
evidenceGroup: EvidenceGroup!
298299
sender: User!
300+
timestamp: BigInt!
299301
}
300302

301303
type ClassicContribution implements Contribution @entity {

subgraph/core/src/EvidenceModule.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export function handleEvidenceEvent(event: EvidenceEvent): void {
1212
evidenceGroup.save();
1313
const evidence = new ClassicEvidence(`${evidenceGroupID}-${evidenceIndex.toString()}`);
1414
const userId = event.params._party.toHexString();
15+
evidence.timestamp = event.block.timestamp;
1516
evidence.evidence = event.params._evidence;
1617
evidence.evidenceGroup = evidenceGroupID.toString();
1718
evidence.sender = userId;

subgraph/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@kleros/kleros-v2-subgraph",
3-
"version": "0.5.0",
3+
"version": "0.5.1",
44
"license": "MIT",
55
"scripts": {
66
"update:core:arbitrum-sepolia-devnet": "./scripts/update.sh arbitrumSepoliaDevnet arbitrum-sepolia core/subgraph.yaml",

web/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
"vite-tsconfig-paths": "^4.3.2"
7575
},
7676
"dependencies": {
77+
"@cyntler/react-doc-viewer": "^1.16.3",
7778
"@filebase/client": "^0.0.5",
7879
"@kleros/kleros-sdk": "workspace:^",
7980
"@kleros/ui-components-library": "^2.12.0",

web/src/app.tsx

Lines changed: 65 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from "react";
1+
import React, { lazy, Suspense } from "react";
22

33
import { Route } from "react-router-dom";
44

@@ -9,17 +9,18 @@ import IsListProvider from "context/IsListProvider";
99
import { NewDisputeProvider } from "context/NewDisputeContext";
1010
import QueryClientProvider from "context/QueryClientProvider";
1111
import StyledComponentsProvider from "context/StyledComponentsProvider";
12+
const Home = lazy(() => import("./pages/Home"));
13+
const Cases = lazy(() => import("./pages/Cases"));
14+
const Dashboard = lazy(() => import("./pages/Dashboard"));
15+
const Courts = lazy(() => import("./pages/Courts"));
16+
const DisputeTemplateView = lazy(() => import("./pages/DisputeTemplateView"));
17+
const DisputeResolver = lazy(() => import("./pages/Resolver"));
18+
const GetPnk = lazy(() => import("./pages/GetPnk"));
1219
import Web3Provider from "context/Web3Provider";
1320

21+
import Loader from "components/Loader";
1422
import Layout from "layout/index";
1523

16-
import Cases from "./pages/Cases";
17-
import Courts from "./pages/Courts";
18-
import Dashboard from "./pages/Dashboard";
19-
import DisputeTemplateView from "./pages/DisputeTemplateView";
20-
import GetPnk from "./pages/GetPnk";
21-
import Home from "./pages/Home";
22-
import DisputeResolver from "./pages/Resolver";
2324
import { SentryRoutes } from "./utils/sentry";
2425

2526
const App: React.FC = () => {
@@ -32,13 +33,62 @@ const App: React.FC = () => {
3233
<NewDisputeProvider>
3334
<SentryRoutes>
3435
<Route path="/" element={<Layout />}>
35-
<Route index element={<Home />} />
36-
<Route path="cases/*" element={<Cases />} />
37-
<Route path="courts/*" element={<Courts />} />
38-
<Route path="dashboard/:page/:order/:filter" element={<Dashboard />} />
39-
<Route path="dispute-template" element={<DisputeTemplateView />} />
40-
<Route path="resolver/*" element={<DisputeResolver />} />
41-
<Route path="get-pnk/*" element={<GetPnk />} />
36+
<Route
37+
index
38+
element={
39+
<Suspense fallback={<Loader width={"48px"} height={"48px"} />}>
40+
<Home />
41+
</Suspense>
42+
}
43+
/>
44+
<Route
45+
path="cases/*"
46+
element={
47+
<Suspense fallback={<Loader width={"48px"} height={"48px"} />}>
48+
<Cases />
49+
</Suspense>
50+
}
51+
/>
52+
<Route
53+
path="courts/*"
54+
element={
55+
<Suspense fallback={<Loader width={"48px"} height={"48px"} />}>
56+
<Courts />
57+
</Suspense>
58+
}
59+
/>
60+
<Route
61+
path="dashboard/:page/:order/:filter"
62+
element={
63+
<Suspense fallback={<Loader width={"48px"} height={"48px"} />}>
64+
<Dashboard />
65+
</Suspense>
66+
}
67+
/>
68+
<Route
69+
path="dispute-template"
70+
element={
71+
<Suspense fallback={<Loader width={"48px"} height={"48px"} />}>
72+
<DisputeTemplateView />
73+
</Suspense>
74+
}
75+
/>
76+
<Route
77+
path="resolver/*"
78+
element={
79+
<Suspense fallback={<Loader width={"48px"} height={"48px"} />}>
80+
<DisputeResolver />
81+
</Suspense>
82+
}
83+
/>
84+
<Route
85+
path="get-pnk/*"
86+
element={
87+
<Suspense fallback={<Loader width={"48px"} height={"48px"} />}>
88+
<GetPnk />
89+
</Suspense>
90+
}
91+
/>
4292
<Route path="*" element={<h1>Justice not found here ¯\_( ͡° ͜ʖ ͡°)_/¯</h1>} />
4393
</Route>
4494
</SentryRoutes>
Lines changed: 10 additions & 0 deletions
Loading

web/src/assets/svgs/icons/new-tab.svg

Lines changed: 3 additions & 0 deletions
Loading

web/src/components/DisputePreview/Alias.tsx

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,49 +5,52 @@ import Skeleton from "react-loading-skeleton";
55
import { isAddress } from "viem";
66
import { useEnsAddress } from "wagmi";
77

8-
import { Alias } from "context/NewDisputeContext";
9-
import { isUndefined } from "utils/index";
10-
118
import { AddressOrName, IdenticonOrAvatar } from "../ConnectWallet/AccountDisplay";
129

1310
const AliasContainer = styled.div`
1411
min-height: 32px;
1512
display: flex;
1613
gap: 8px;
1714
align-items: center;
15+
max-width: 100%;
1816
`;
1917

2018
const TextContainer = styled.div`
2119
display: flex;
20+
flex-wrap: wrap;
21+
max-width: 100%;
2222
> label {
2323
color: ${({ theme }) => theme.primaryText};
2424
font-size: 14px;
25+
word-wrap: break-word;
26+
max-width: 100%;
2527
}
2628
`;
2729

2830
interface IAlias {
29-
alias: Alias;
31+
name: string;
32+
address: `0x${string}`;
3033
}
3134

32-
const AliasDisplay: React.FC<IAlias> = ({ alias }) => {
35+
const AliasDisplay: React.FC<IAlias> = ({ name, address }) => {
3336
const { data: addressFromENS, isLoading } = useEnsAddress({
3437
query: {
3538
// if alias.address is not an Address, we treat it as ENS and try to fetch address from there
36-
enabled: !isAddress(alias.address),
39+
enabled: !isAddress(address),
3740
},
38-
name: alias.address,
41+
name: address,
3942
chainId: 1,
4043
});
4144

4245
// try fetching ens name, else go with address
43-
const address = addressFromENS ?? (alias.address as `0x${string}`);
46+
const resolvedAddress = addressFromENS ?? (address as `0x${string}`);
4447

4548
return (
4649
<AliasContainer>
47-
{isLoading ? <Skeleton width={30} height={24} /> : <IdenticonOrAvatar address={address} size="24" />}
50+
{isLoading ? <Skeleton width={30} height={24} /> : <IdenticonOrAvatar address={resolvedAddress} size="24" />}
4851
<TextContainer>
49-
{isLoading ? <Skeleton width={30} height={24} /> : <AddressOrName address={address} />}&nbsp;
50-
{!isUndefined(alias.name) && alias.name !== "" ? <label>({alias.name})</label> : null}
52+
{isLoading ? <Skeleton width={30} height={24} /> : <AddressOrName address={resolvedAddress} />}&nbsp;
53+
<label>({name})</label>
5154
</TextContainer>
5255
</AliasContainer>
5356
);

web/src/components/DisputePreview/DisputeContext.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@ import AliasDisplay from "./Alias";
1616

1717
const StyledH1 = styled.h1`
1818
margin: 0;
19+
word-wrap: break-word;
1920
`;
2021

2122
const QuestionAndDescription = styled.div`
2223
display: flex;
2324
flex-direction: column;
25+
word-wrap: break-word;
2426
div:first-child p:first-of-type {
2527
font-size: 16px;
2628
font-weight: 600;
@@ -47,6 +49,9 @@ const Answer = styled.div`
4749
display: flex;
4850
flex-wrap: wrap;
4951
gap: ${responsiveSize(2, 8)};
52+
> label {
53+
max-width: 100%;
54+
}
5055
`;
5156

5257
const AliasesContainer = styled.div`
@@ -103,8 +108,8 @@ export const DisputeContext: React.FC<IDisputeContext> = ({ disputeDetails, isRp
103108
<>
104109
<Divider />
105110
<AliasesContainer>
106-
{disputeDetails.aliases.map((alias) => (
107-
<AliasDisplay alias={alias} key={alias.address} />
111+
{Object.keys(disputeDetails.aliases).map((key) => (
112+
<AliasDisplay name={key} key={key} address={disputeDetails.aliases[key]} />
108113
))}
109114
</AliasesContainer>
110115
</>

web/src/components/DisputeView/DisputeInfo/DisputeInfoCard.tsx

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,17 @@ const RestOfFieldsContainer = styled.div<{ isOverview?: boolean }>`
5252
`};
5353
`;
5454

55+
const StyledField = styled(Field)`
56+
max-width: 100%;
57+
label {
58+
&.value {
59+
margin-left: 8px;
60+
overflow: hidden;
61+
text-overflow: ellipsis;
62+
}
63+
}
64+
`;
65+
5566
type IDisputeInfoCard = { fieldItems: FieldItem[] } & IDisputeInfo;
5667

5768
const DisputeInfoCard: React.FC<IDisputeInfoCard> = ({
@@ -75,12 +86,12 @@ const DisputeInfoCard: React.FC<IDisputeInfoCard> = ({
7586
<Container>
7687
{court && courtId && isOverview && (
7788
<CourtBranchFieldContainer>
78-
<Field icon={LawBalanceIcon} name="Court Branch" value={courtBranchValue} {...{ isOverview }} />
89+
<StyledField icon={LawBalanceIcon} name="Court Branch" value={courtBranchValue} {...{ isOverview }} />
7990
</CourtBranchFieldContainer>
8091
)}
8192
<RestOfFieldsContainer {...{ isOverview }}>
8293
{fieldItems.map((item) =>
83-
item.display ? <Field key={item.name} {...(item as IField)} {...{ isOverview }} /> : null
94+
item.display ? <StyledField key={item.name} {...(item as IField)} {...{ isOverview }} /> : null
8495
)}
8596
</RestOfFieldsContainer>
8697
{showLabels ? <CardLabel disputeId={disputeID} round={round - 1} /> : null}

0 commit comments

Comments
 (0)