Skip to content

Commit

Permalink
Merge pull request #179 from topmonks/162-metadata-explorer
Browse files Browse the repository at this point in the history
Metadata explorer
  • Loading branch information
uiii committed Dec 5, 2023
2 parents 444ff87 + d4897e9 commit c0f084f
Show file tree
Hide file tree
Showing 90 changed files with 4,771 additions and 427 deletions.
1,814 changes: 1,814 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"http-status-codes": "^2.3.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-markdown": "^9.0.1",
"react-router-dom": "^6.17.0",
"react-scripts": "5.0.1",
"rollbar": "^2.26.1",
Expand Down
3 changes: 0 additions & 3 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ import { RouterProvider } from "react-router-dom";
import { ThemeProvider } from "@mui/material";
import { Provider as RollbarProvider } from "@rollbar/react";

import { Devtools } from "./components/Devtools";

import { theme } from "./theme";
import { rollbar } from "./rollbar";
import { router } from "./router";
Expand All @@ -13,7 +11,6 @@ function App() {
<RollbarProvider instance={rollbar}>
<ThemeProvider theme={theme}>
<RouterProvider router={router} />
<Devtools />
</ThemeProvider>
</RollbarProvider>
);
Expand Down
33 changes: 14 additions & 19 deletions src/components/DataViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,12 @@ import { css, Theme } from "@emotion/react";
import { IconButton, Modal, ToggleButton, ToggleButtonGroup } from "@mui/material";
import { Close } from "@mui/icons-material";

import { config } from "../config";

import { DecodedArg } from "../model/decodedMetadata";
import { Network } from "../model/network";
import { RuntimeMetadataArg } from "../model/runtime-metadata/runtimeMetadataArg";

import CopyToClipboardButton from "./CopyToClipboardButton";
import { DataViewerValueJson } from "./DataViewerValueJson";
import { DataViewerValueParsed } from "./DataViewerValueParsed";
import { Devtool } from "./Devtool";

const dataViewerStyle = css`
display: flex;
Expand Down Expand Up @@ -126,27 +123,26 @@ const closeButtonStyle = css`
z-index: 10;
`;

export type DataViewerMode = "json" | "parsed" | "meta";
export type DataViewerMode = "json" | "parsed";

const MODES: (DataViewerMode|false)[] = [
const MODES: DataViewerMode[] = [
"parsed",
"json",
config.devtools.enabled && "meta"
"json"
];

const modeLabels: Record<DataViewerMode, ReactNode> = {
parsed: "Parsed",
json: "Raw",
meta: <Devtool>Meta</Devtool>
};

type ModeSelectProps = {
modes: DataViewerMode[];
value: DataViewerMode;
onChange: (mode: DataViewerMode) => void;
};

const ModeSelect = (props: ModeSelectProps) => {
const {value, onChange} = props;
const {modes, value, onChange} = props;

return (
<ToggleButtonGroup
Expand All @@ -155,7 +151,7 @@ const ModeSelect = (props: ModeSelectProps) => {
value={value}
onChange={(_, mode) => mode && onChange(mode)}
>
{MODES.map(mode => mode &&
{modes.map(mode => mode &&
<ToggleButton key={mode} css={modeButtonStyle} value={mode}>
{modeLabels[mode]}
</ToggleButton>
Expand Down Expand Up @@ -205,8 +201,8 @@ const DataViewerModalHandle = (props: DataViewerModalHandleProps) => {
export type DataViewerProps = {
network: Network;
data: any;
metadata?: DecodedArg[];
modes?: DataViewerMode[];
rawData?: any;
metadata?: RuntimeMetadataArg[];
defaultMode?: DataViewerMode;
simple?: boolean;
copyToClipboard?: boolean;
Expand All @@ -216,6 +212,7 @@ export const DataViewer = (props: DataViewerProps) => {
const {
network,
data,
rawData = data,
metadata,
defaultMode = MODES.find(Boolean),
simple,
Expand All @@ -235,8 +232,8 @@ export const DataViewer = (props: DataViewerProps) => {
}, [data]);

const jsonContent = useMemo(() => (!simple || defaultMode === "json") && (
<DataViewerValueJson value={data} />
), [data]);
<DataViewerValueJson value={rawData} />
), [rawData]);

const parsedContent = useMemo(() => (!simple || defaultMode === "parsed") && (
<DataViewerValueParsed
Expand All @@ -256,19 +253,18 @@ export const DataViewer = (props: DataViewerProps) => {
]}
>
<div css={[controlsStyle, simple && simpleControlsStyle]}>
{!simple && <ModeSelect value={mode} onChange={setMode} />}
{!simple && <ModeSelect modes={MODES} value={mode} onChange={setMode} />}
{copyToClipboard && <CopyToClipboardButton value={copyToClipboardValue} css={copyButtonStyle} />}
{!simple &&
<DataViewerModalHandle>
<div css={dataViewerStyle}>
<div css={[controlsStyle]}>
<ModeSelect value={mode} onChange={setMode} />
<ModeSelect modes={MODES} value={mode} onChange={setMode} />
{copyToClipboard && <CopyToClipboardButton value={copyToClipboardValue} css={copyButtonStyle} />}
</div>
<div css={scrollAreaStyle}>
{mode === "json" && jsonContent}
{mode === "parsed" && parsedContent}
{metadata && mode === "meta" && <DataViewerValueJson value={metadata} />}
</div>
</div>
</DataViewerModalHandle>
Expand All @@ -277,7 +273,6 @@ export const DataViewer = (props: DataViewerProps) => {
<div css={scrollAreaStyle}>
{mode === "json" && jsonContent}
{mode === "parsed" && parsedContent}
{mode === "meta" && <DataViewerValueJson value={metadata} />}
</div>
</div>
);
Expand Down
12 changes: 6 additions & 6 deletions src/components/DataViewerValueParsed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { Table, TableBody, TableCell, TableRow } from "@mui/material";
import { css } from "@emotion/react";

import { DecodedArg } from "../model/decodedMetadata";
import { RuntimeMetadataArg } from "../model/runtime-metadata/runtimeMetadataArg";
import { noCase } from "../utils/string";

import { AccountAddress } from "./account/AccountAddress";
Expand Down Expand Up @@ -77,7 +77,7 @@ type ValueOfKindProps = {
__kind: string,
value: any;
};
valueMetadata?: DecodedArg;
valueMetadata?: RuntimeMetadataArg;
}

const ValueOfKind = (props: ValueOfKindProps) => {
Expand Down Expand Up @@ -110,7 +110,7 @@ const ValueOfKind = (props: ValueOfKindProps) => {
type MaybeAccountLinkValueProps = {
network: Network;
value: any;
valueMetadata: DecodedArg;
valueMetadata: RuntimeMetadataArg;
}

const AccountValue = (props: MaybeAccountLinkValueProps) => {
Expand Down Expand Up @@ -150,19 +150,19 @@ const AccountValue = (props: MaybeAccountLinkValueProps) => {
export type DataViewerValueParsedProps = {
network: Network;
value: any;
metadata?: DecodedArg[]|DecodedArg;
metadata?: RuntimeMetadataArg[]|RuntimeMetadataArg;
};

export const DataViewerValueParsed = (props: DataViewerValueParsedProps) => {
const { network, metadata } = props;
let { value } = props;

if (metadata && ADDRESS_TYPES.includes((metadata as DecodedArg).type)) {
if (metadata && ADDRESS_TYPES.includes((metadata as RuntimeMetadataArg).type)) {
return (
<AccountValue
network={network}
value={value}
valueMetadata={metadata as DecodedArg}
valueMetadata={metadata as RuntimeMetadataArg}
/>
);
}
Expand Down
54 changes: 0 additions & 54 deletions src/components/Devtool.tsx

This file was deleted.

14 changes: 0 additions & 14 deletions src/components/Devtools.tsx

This file was deleted.

73 changes: 40 additions & 33 deletions src/components/NetworkSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,8 @@ const buttonStyle = css`
padding-left: 16px;
padding-right: 8px;
flex: 1 0 auto;
border-radius: 8px;
border: solid 1px #c4cdd5;
border-right: none;
border: solid 1px #bdbdbd;
font-size: 1rem;
font-weight: 400;
Expand Down Expand Up @@ -91,11 +88,12 @@ const checkboxStyle = css`

interface NetworkSelectProps extends Omit<ButtonProps, "value" | "onChange"> {
value: Network[];
multiselect?: boolean;
onChange: (value: Network[], isUserAction: boolean) => void;
}

export const NetworkSelect = (props: NetworkSelectProps) => {
const { value, onChange, ...buttonProps } = props;
const { value, multiselect, onChange, ...buttonProps } = props;

const networkGroups = useNetworkGroups();

Expand Down Expand Up @@ -194,7 +192,7 @@ export const NetworkSelect = (props: NetworkSelectProps) => {
)}
{value.length > 1 && (
<>
{value.slice(0, 3).map((network) => <img src={network.icon} css={iconStyle} />)}
{value.slice(0, 3).map((network) => <img src={network.icon} css={iconStyle} key={network.name} />)}
{value.length > 3 && <span>+ {value.length - 3} other</span>}
</>
)}
Expand All @@ -209,40 +207,47 @@ export const NetworkSelect = (props: NetworkSelectProps) => {
"aria-labelledby": "basic-button",
}}
>
<MenuItem
css={menuItemStyle}
selected={value.length === 0}
onClick={() => setSelection([])}
>
<ListItemIcon>
<AllIcon css={[iconStyle, {color: "#e6007a"}]} />
</ListItemIcon>
<ListItemText>All networks</ListItemText>
</MenuItem>
{multiselect && [
<MenuItem
css={menuItemStyle}
selected={value.length === 0}
onClick={() => setSelection([])}
key={"all"}
>
<ListItemIcon>
<AllIcon css={[iconStyle, {color: "#e6007a"}]} />
</ListItemIcon>
<ListItemText>All networks</ListItemText>
</MenuItem>,
<Divider key="all-divider" />
]}
{networkGroups.map((group, index) => {
const allSelected = group.networks.every(it => value.includes(it));

return [
<Divider />,
<ListSubheader css={headerStyle} key={index}>
index > 0 && <Divider key={`divider-${index}`} />,
<ListSubheader css={headerStyle} key={`subheader-${index}`}>
<div>
{group.relayChainNetwork?.displayName || "Other"}{" "}
{group.relayChainNetwork && <><br /><span style={{fontSize: 12}}>and parachains</span></>}
</div>
<Link
onClick={() => allSelected
? removeSelection(group.networks)
: addSelection(group.networks)
}
>
{allSelected ? "deselect" : "select"} all
</Link>
{multiselect && (
<Link
onClick={() => allSelected
? removeSelection(group.networks)
: addSelection(group.networks)
}
>
{allSelected ? "deselect" : "select"} all
</Link>
)}
</ListSubheader>,
group.networks.map((network) => (
<MenuItem
css={menuItemStyle}
selected={value.includes(network)}
onClick={(ev) => handleItemClick(network, ev)}
key={network.name}
>
<ListItemIcon>
<img
Expand All @@ -251,13 +256,15 @@ export const NetworkSelect = (props: NetworkSelectProps) => {
/>
</ListItemIcon>
<ListItemText>{network.displayName}</ListItemText>
<Checkbox
css={checkboxStyle}
checked={value.includes(network)}
onChange={(ev, checked) => checked ? addSelection([network]) : removeSelection([network])}
onClick={(ev) => ev.stopPropagation()}
disableRipple
/>
{multiselect && (
<Checkbox
css={checkboxStyle}
checked={value.includes(network)}
onChange={(ev, checked) => checked ? addSelection([network]) : removeSelection([network])}
onClick={(ev) => ev.stopPropagation()}
disableRipple
/>
)}
</MenuItem>
))
];
Expand Down
Loading

0 comments on commit c0f084f

Please sign in to comment.