Fix #482 allow resetting objects and maps on invalid type

This commit is contained in:
Misode
2024-03-11 20:55:32 +01:00
parent 9dbcf46a53
commit 4851da4e9d

View File

@@ -199,9 +199,12 @@ const renderHtml: RenderHook = {
return [null, suffix, body] return [null, suffix, body]
}, },
map({ children, keys, config }, path, value, lang, version, states, ctx) { map({ children, keys, config, node }, path, value, lang, version, states, ctx) {
const { expand, collapse, isToggled } = useToggles() const { expand, collapse, isToggled } = useToggles()
let suffix: JSX.Element | null = null
let body: JSX.Element | null = null
const keyPath = new ModelPath(keysModel, new Path([hashString(path.toString())], path.contextArr)) const keyPath = new ModelPath(keysModel, new Path([hashString(path.toString())], path.contextArr))
const onAdd = () => { const onAdd = () => {
const key = keyPath.get() const key = keyPath.get()
@@ -227,12 +230,14 @@ const renderHtml: RenderHook = {
}) })
return ObjectNode(Object.fromEntries(properties)).hook(this, path, value, lang, version, states, ctx) return ObjectNode(Object.fromEntries(properties)).hook(this, path, value, lang, version, states, ctx)
} }
const suffix = <>
{keysSchema.hook(this, keyPath, keyPath.get() ?? '', lang, version, states, ctx)[1]} if (typeof value === 'object' && value !== null) {
<button class="add tooltipped tip-se" aria-label={localize(lang, 'add')} onClick={onAdd}>{Octicon.plus_circle}</button> suffix = <>
</> {suffix}
const body = <> {keysSchema.hook(this, keyPath, keyPath.get() ?? '', lang, version, states, ctx)[1]}
{typeof value === 'object' && Object.entries(value).map(([key, cValue]) => { <button class="add tooltipped tip-se" aria-label={localize(lang, 'add')} onClick={onAdd}>{Octicon.plus_circle}</button>
</>
body = <>{Object.entries(value).map(([key, cValue]) => {
const pathWithContext = (config?.context) ? new ModelPath(path.getModel(), new Path(path.getArray(), [config.context])) : path const pathWithContext = (config?.context) ? new ModelPath(path.getModel(), new Path(path.getArray(), [config.context])) : path
const cPath = pathWithContext.modelPush(key) const cPath = pathWithContext.modelPush(key)
const canToggle = children.type(cPath) === 'object' const canToggle = children.type(cPath) === 'object'
@@ -257,8 +262,11 @@ const renderHtml: RenderHook = {
{canToggle && <button class="toggle tooltipped tip-se" aria-label={`${localize(lang, 'collapse')}\n${localize(lang, 'collapse_all', 'Ctrl')}`} onClick={collapse(key)}>{Octicon.chevron_down}</button>} {canToggle && <button class="toggle tooltipped tip-se" aria-label={`${localize(lang, 'collapse')}\n${localize(lang, 'collapse_all', 'Ctrl')}`} onClick={collapse(key)}>{Octicon.chevron_down}</button>}
<button class="remove tooltipped tip-se" aria-label={localize(lang, 'remove')} onClick={onRemove}>{Octicon.trashcan}</button> <button class="remove tooltipped tip-se" aria-label={localize(lang, 'remove')} onClick={onRemove}>{Octicon.trashcan}</button>
</MemoedTreeNode> </MemoedTreeNode>
})} })}</>
</> } else {
const onReset = () => path.set(DataModel.wrapLists(node.default()))
suffix = <>{suffix}<button class="add tooltipped tip-se" aria-label={localize(lang, 'reset')} onClick={onReset}>{Octicon.history}</button></>
}
return [null, suffix, body] return [null, suffix, body]
}, },
@@ -278,11 +286,12 @@ const renderHtml: RenderHook = {
let prefix: JSX.Element | null = null let prefix: JSX.Element | null = null
let suffix: JSX.Element | null = null let suffix: JSX.Element | null = null
let body: JSX.Element | null = null
if (node.optional()) { if (node.optional()) {
if (value === undefined) { if (value === undefined) {
const onExpand = () => path.set(DataModel.wrapLists(node.default())) const onExpand = () => path.set(DataModel.wrapLists(node.default()))
suffix = <button class="node-collapse closed tooltipped tip-se" aria-label={localize(lang, 'expand')} onClick={onExpand}>{Octicon.plus_circle}</button> suffix = <button class="node-collapse closed tooltipped tip-se" aria-label={localize(lang, 'expand')} onClick={onExpand}>{Octicon.plus_circle}</button>
} else { } else if (typeof value === 'object' && value !== null){
const onCollapse = () => path.set(undefined) const onCollapse = () => path.set(undefined)
suffix = <button class="node-collapse open tooltipped tip-se" aria-label={localize(lang, 'remove')} onClick={onCollapse}>{Octicon.trashcan}</button> suffix = <button class="node-collapse open tooltipped tip-se" aria-label={localize(lang, 'remove')} onClick={onCollapse}>{Octicon.trashcan}</button>
} }
@@ -298,12 +307,11 @@ const renderHtml: RenderHook = {
return [prefix, suffix, null] return [prefix, suffix, null]
} }
} }
if (!(node.optional() && value === undefined)) {
const newCtx = (typeof value === 'object' && value !== null && node.default()?.pools) if (typeof value === 'object' && value !== null) {
? { ...ctx, loot: value?.type } : ctx const newCtx = (typeof value === 'object' && value !== null && node.default()?.pools)
const body = <> ? { ...ctx, loot: value?.type } : ctx
{(typeof value === 'object' && value !== null && !(node.optional() && value === undefined)) && body = <>{Object.entries(getActiveFields(path))
Object.entries(getActiveFields(path))
.filter(([_, child]) => child.enabled(path)) .filter(([_, child]) => child.enabled(path))
.map(([key, child]) => { .map(([key, child]) => {
const cPath = getChildModelPath(path, key) const cPath = getChildModelPath(path, key)
@@ -318,9 +326,12 @@ const renderHtml: RenderHook = {
return isFlattened ? cBody : null return isFlattened ? cBody : null
} }
return <MemoedTreeNode key={key} schema={child} path={cPath} value={value[key]} {...{lang, version, states, ctx: newCtx}} /> return <MemoedTreeNode key={key} schema={child} path={cPath} value={value[key]} {...{lang, version, states, ctx: newCtx}} />
}) })}</>
} else {
const onReset = () => path.set(DataModel.wrapLists(node.default()))
suffix = <>{suffix}<button class="add tooltipped tip-se" aria-label={localize(lang, 'reset')} onClick={onReset}>{Octicon.history}</button></>
} }
</> }
return [prefix, suffix, body] return [prefix, suffix, body]
}, },