split metadata page into separate tabs
This commit is contained in:
@@ -25,6 +25,7 @@ export const CopyText: React.FC<{
|
||||
|
||||
return (
|
||||
<button
|
||||
aria-label={binary ? "copy binary" : "copy"}
|
||||
disabled={disabled || copied}
|
||||
className={twMerge(className, disabled ? "opacity-50" : "")}
|
||||
onClick={copy}
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
useState,
|
||||
} from "react"
|
||||
import { Link } from "react-router-dom"
|
||||
import { twMerge } from "tailwind-merge"
|
||||
|
||||
export const Lookup: FC = () => {
|
||||
const [id, setId] = useState(0)
|
||||
@@ -25,7 +26,7 @@ export const Lookup: FC = () => {
|
||||
type="number"
|
||||
/>
|
||||
</label>
|
||||
<div className="border-t max-h-[75vh] overflow-auto">
|
||||
<div className="border-t">
|
||||
<LookupNode id={id} />
|
||||
</div>
|
||||
</div>
|
||||
@@ -71,7 +72,12 @@ export const LookupLink: FC<{ id: number }> = ({ id }) => {
|
||||
const [expanded, setExpanded] = useState(false)
|
||||
|
||||
return (
|
||||
<div className="border rounded p-2">
|
||||
<div
|
||||
className={twMerge(
|
||||
"border rounded p-2",
|
||||
expanded && "bg-slate-500 bg-opacity-10",
|
||||
)}
|
||||
>
|
||||
<button
|
||||
onClick={() => setExpanded((e) => !e)}
|
||||
className="flex items-center gap-1"
|
||||
|
||||
@@ -5,15 +5,14 @@ import { JsonDisplay } from "@/components/JsonDisplay"
|
||||
import { LoadingMetadata } from "@/components/Loading"
|
||||
import { withSubscribe } from "@/components/withSuspense"
|
||||
import { getTypeComplexity } from "@/utils/shape"
|
||||
import { V14, V15 } from "@polkadot-api/substrate-bindings"
|
||||
import { useStateObservable } from "@react-rxjs/core"
|
||||
import { FC, useState } from "react"
|
||||
import { useState } from "react"
|
||||
import { Route, Routes, useParams } from "react-router-dom"
|
||||
import { Extrinsic } from "./Extrinsic"
|
||||
import { Lookup, LookupContext } from "./Lookup"
|
||||
import { Pallets } from "./Pallets"
|
||||
import { RuntimeApis } from "./RuntimeApis"
|
||||
import { V15Fields } from "./V15Fields"
|
||||
import { Custom, OuterEnums } from "./V15Fields"
|
||||
|
||||
export const Metadata = withSubscribe(
|
||||
() => (
|
||||
@@ -28,43 +27,66 @@ export const Metadata = withSubscribe(
|
||||
)
|
||||
|
||||
const MetadataExplorer = () => {
|
||||
const [mode, setMode] = useState<"json" | "explorer">("explorer")
|
||||
const [mode, setMode] = useState<string>("pallets")
|
||||
const metadata = useStateObservable(metadata$)
|
||||
|
||||
const tabs = [
|
||||
{
|
||||
id: "pallets",
|
||||
label: "Pallets",
|
||||
element: <Pallets pallets={metadata.pallets} />,
|
||||
},
|
||||
{
|
||||
id: "apis",
|
||||
label: "Runtime APIs",
|
||||
element: <RuntimeApis apis={metadata.apis} />,
|
||||
},
|
||||
{
|
||||
id: "extrinsic",
|
||||
label: "Extrinsic",
|
||||
element: <Extrinsic extrinsic={metadata.extrinsic} />,
|
||||
},
|
||||
{
|
||||
id: "lookup",
|
||||
label: "Lookup",
|
||||
element: <Lookup />,
|
||||
},
|
||||
...("outerEnums" in metadata
|
||||
? [
|
||||
{
|
||||
id: "outerEnums",
|
||||
label: "Outer Enums",
|
||||
element: <OuterEnums metadata={metadata} />,
|
||||
},
|
||||
{
|
||||
id: "custom",
|
||||
label: "Custom",
|
||||
element: <Custom metadata={metadata} />,
|
||||
disabled: metadata.custom.length === 0,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
{
|
||||
id: "json",
|
||||
label: "JSON",
|
||||
element: <JsonDisplay src={metadata} />,
|
||||
},
|
||||
].filter((v) => !v.disabled)
|
||||
|
||||
return (
|
||||
<div className="p-4 pb-0 flex flex-col overflow-auto items-start gap-2">
|
||||
<ButtonGroup
|
||||
value={mode}
|
||||
onValueChange={setMode as any}
|
||||
items={[
|
||||
{
|
||||
value: "explorer",
|
||||
content: "Explorer",
|
||||
},
|
||||
{
|
||||
value: "json",
|
||||
content: "JSON",
|
||||
},
|
||||
]}
|
||||
items={tabs.map((tab) => ({
|
||||
value: tab.id,
|
||||
content: tab.label,
|
||||
}))}
|
||||
/>
|
||||
{mode === "json" ? (
|
||||
<JsonDisplay src={metadata} />
|
||||
) : (
|
||||
<DecodedExplorer value={metadata} />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const DecodedExplorer: FC<{ value: V14 | V15 }> = ({ value }) => {
|
||||
return (
|
||||
<div className="w-full flex flex-col gap-6">
|
||||
<LookupContext.Provider value={value.lookup}>
|
||||
<Lookup />
|
||||
<Pallets pallets={value.pallets} />
|
||||
<RuntimeApis apis={value.apis} />
|
||||
<Extrinsic extrinsic={value.extrinsic} />
|
||||
{"outerEnums" in value && <V15Fields metadata={value} />}
|
||||
<LookupContext.Provider value={metadata.lookup}>
|
||||
<div className="w-full flex flex-col">
|
||||
{tabs.find((t) => t.id === mode)?.element}
|
||||
</div>
|
||||
</LookupContext.Provider>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -10,7 +10,6 @@ export const Pallets: FC<{ pallets: Array<Pallet> }> = ({ pallets }) => {
|
||||
|
||||
return (
|
||||
<div className="border rounded p-2 flex flex-col gap-2">
|
||||
<h3 className="font-bold text-xl">Pallets</h3>
|
||||
<label className="self-start">
|
||||
Pallet:{" "}
|
||||
<SearchableSelect
|
||||
|
||||
@@ -1,43 +1,38 @@
|
||||
import { CopyText } from "@/components/Copy"
|
||||
import { V15 } from "@polkadot-api/substrate-bindings"
|
||||
import { FC } from "react"
|
||||
import { LookupLink } from "./Lookup"
|
||||
import { CopyText } from "@/components/Copy"
|
||||
|
||||
export const V15Fields: FC<{ metadata: V15 }> = ({ metadata }) => {
|
||||
return (
|
||||
<>
|
||||
<div className="border rounded p-2 flex flex-col gap-2">
|
||||
<h3 className="font-bold text-xl">Outer Enums</h3>
|
||||
<div>
|
||||
<h4>Call</h4>
|
||||
<LookupLink id={metadata.outerEnums.call} />
|
||||
export const OuterEnums: FC<{ metadata: V15 }> = ({ metadata }) => (
|
||||
<div className="border rounded p-2 flex flex-col gap-2">
|
||||
<div>
|
||||
<h4>Call</h4>
|
||||
<LookupLink id={metadata.outerEnums.call} />
|
||||
</div>
|
||||
<div>
|
||||
<h4>Event</h4>
|
||||
<LookupLink id={metadata.outerEnums.event} />
|
||||
</div>
|
||||
<div>
|
||||
<h4>Error</h4>
|
||||
<LookupLink id={metadata.outerEnums.error} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
export const Custom: FC<{ metadata: V15 }> = ({ metadata }) => (
|
||||
<div className="border rounded p-2 flex flex-col gap-2">
|
||||
{Object.entries(
|
||||
metadata.custom.map(([key, { type, value }]) => (
|
||||
<div key={key}>
|
||||
<h4>{key}</h4>
|
||||
<LookupLink id={type} />
|
||||
<div className="whitespace-nowrap overflow-hidden text-ellipsis">
|
||||
<CopyText text={value} binary className="mr-2" />
|
||||
{value}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Event</h4>
|
||||
<LookupLink id={metadata.outerEnums.event} />
|
||||
</div>
|
||||
<div>
|
||||
<h4>Error</h4>
|
||||
<LookupLink id={metadata.outerEnums.error} />
|
||||
</div>
|
||||
</div>
|
||||
{metadata.custom.length > 0 && (
|
||||
<div className="border rounded p-2 flex flex-col gap-2">
|
||||
<h3 className="font-bold text-xl">Custom</h3>
|
||||
{Object.entries(
|
||||
metadata.custom.map(([key, { type, value }]) => (
|
||||
<div key={key}>
|
||||
<h4>{key}</h4>
|
||||
<LookupLink id={type} />
|
||||
<div className="whitespace-nowrap overflow-hidden text-ellipsis">
|
||||
<CopyText text={value} binary className="mr-2" />
|
||||
{value}
|
||||
</div>
|
||||
</div>
|
||||
)),
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
)),
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -311,7 +311,7 @@ const KeyDisplay: FC = () => {
|
||||
>
|
||||
{key ?? "Fill in all the storage keys to calculate the encoded key"}
|
||||
</div>
|
||||
<CopyText text={key ?? ""} disabled={key === null} />
|
||||
<CopyText text={key ?? ""} disabled={key === null} binary />
|
||||
{keys.length === keysEnabled && (
|
||||
<BinaryEditButton
|
||||
initialValue={key ? Binary.fromHex(key).asBytes() : undefined}
|
||||
|
||||
Reference in New Issue
Block a user