feat: automatically set default values when editing a lookup type
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { SearchableSelect } from "@/components/Select"
|
||||
import { isEnumComplex, isEnumVoid } from "@/utils/shape"
|
||||
import { getEnumDefaultValue, isEnumComplex } from "@/utils/shape"
|
||||
import { EditEnum, NOTIN } from "@polkadot-api/react-builder"
|
||||
import { Marker } from "../common/Markers"
|
||||
import { useSubtreeFocus } from "../common/SubtreeFocus"
|
||||
@@ -43,7 +43,7 @@ export const CEnum: EditEnum = ({
|
||||
<SearchableSelect
|
||||
setValue={(selected: string | null) => {
|
||||
if (selected && options.includes(selected)) {
|
||||
const value = isEnumVoid(shape, selected) ? null : NOTIN
|
||||
const value = getEnumDefaultValue(shape, selected)
|
||||
onValueChanged({ type: selected, value })
|
||||
}
|
||||
}}
|
||||
|
||||
@@ -3,12 +3,14 @@ import { CirclePlus } from "lucide-react"
|
||||
import { twMerge as clsx } from "tailwind-merge"
|
||||
import { ListItem } from "../common/ListItem"
|
||||
import { useSubtreeFocus } from "../common/SubtreeFocus"
|
||||
import { getDefaultValue } from "@/utils"
|
||||
|
||||
export const CSequence: EditSequence = ({
|
||||
innerComponents,
|
||||
value,
|
||||
onValueChanged,
|
||||
path,
|
||||
shape,
|
||||
}) => {
|
||||
const focus = useSubtreeFocus()
|
||||
const sub = focus.getNextPath(path)
|
||||
@@ -18,7 +20,7 @@ export const CSequence: EditSequence = ({
|
||||
|
||||
const addItem = () => {
|
||||
const curr = value !== NOTIN ? value.slice() : []
|
||||
curr.push(NOTIN)
|
||||
curr.push(getDefaultValue(shape.value))
|
||||
onValueChanged([...curr])
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import SliderToggle from "@/components/Toggle"
|
||||
import { getDefaultValue } from "@/utils"
|
||||
import {
|
||||
EditArray,
|
||||
EditBool,
|
||||
EditOption,
|
||||
EditResult,
|
||||
EditVoid,
|
||||
NOTIN,
|
||||
} from "@polkadot-api/react-builder"
|
||||
import { FC, ReactNode, useState } from "react"
|
||||
import { twMerge } from "tailwind-merge"
|
||||
@@ -61,7 +61,12 @@ export const CArray: EditArray = ({ innerComponents, path }) => {
|
||||
)
|
||||
}
|
||||
|
||||
export const COption: EditOption = ({ value, inner, onValueChanged }) => {
|
||||
export const COption: EditOption = ({
|
||||
value,
|
||||
inner,
|
||||
shape,
|
||||
onValueChanged,
|
||||
}) => {
|
||||
const selected = value !== undefined
|
||||
return (
|
||||
<div>
|
||||
@@ -69,7 +74,9 @@ export const COption: EditOption = ({ value, inner, onValueChanged }) => {
|
||||
<SliderToggle
|
||||
isToggled={selected}
|
||||
toggle={() =>
|
||||
!selected ? onValueChanged(NOTIN) : onValueChanged(undefined)
|
||||
!selected
|
||||
? onValueChanged(getDefaultValue(shape.value))
|
||||
: onValueChanged(undefined)
|
||||
}
|
||||
/>
|
||||
<span className="text-base">
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import { EnumVar, StructVar, Var } from "@polkadot-api/metadata-builders"
|
||||
import { NOTIN } from "@polkadot-api/react-builder"
|
||||
import { Enum } from "polkadot-api"
|
||||
import { mapObject } from "polkadot-api/utils"
|
||||
|
||||
const complexTypes = new Set<Var["type"]>([
|
||||
"tuple",
|
||||
@@ -40,14 +43,49 @@ export const getStructInnerType = <T extends StructVar>(
|
||||
return shape.value[key].type
|
||||
}
|
||||
|
||||
export const isEnumVoid = <T extends EnumVar>(
|
||||
const MAX_DEPTH = 5
|
||||
export const getDefaultValue = (innerVar: Var, depth = 0): any => {
|
||||
if (depth > MAX_DEPTH) return NOTIN
|
||||
const nextDefault = (v: Var) => getDefaultValue(v, depth + 1)
|
||||
|
||||
switch (innerVar.type) {
|
||||
case "void":
|
||||
return null
|
||||
case "option":
|
||||
return undefined
|
||||
case "sequence":
|
||||
return []
|
||||
case "struct":
|
||||
return mapObject(innerVar.value, (v) => nextDefault(v))
|
||||
case "array":
|
||||
return new Array(innerVar.len)
|
||||
.fill(0)
|
||||
.map(() => nextDefault(innerVar.value))
|
||||
case "tuple":
|
||||
return innerVar.value.map(nextDefault)
|
||||
case "enum": {
|
||||
const selected = Object.entries(innerVar.value)[0]
|
||||
return selected
|
||||
? Enum(
|
||||
selected[0],
|
||||
nextDefault(
|
||||
selected[1].type === "lookupEntry"
|
||||
? selected[1].value
|
||||
: selected[1],
|
||||
),
|
||||
)
|
||||
: NOTIN
|
||||
}
|
||||
}
|
||||
return NOTIN
|
||||
}
|
||||
|
||||
export const getEnumDefaultValue = <T extends EnumVar>(
|
||||
shape: T,
|
||||
type: keyof T["value"],
|
||||
): boolean => {
|
||||
const innerShape = shape.value[type]
|
||||
const innerType =
|
||||
innerShape.type === "lookupEntry" ? innerShape.value.type : innerShape.type
|
||||
return innerType === "void"
|
||||
) => {
|
||||
const innerVar = getEnumInnerVar(shape, type)
|
||||
return getDefaultValue(innerVar)
|
||||
}
|
||||
|
||||
export const getFinalType = (shape: any, name: string) => {
|
||||
|
||||
Reference in New Issue
Block a user