diff --git a/src/app/hooks/customValidation.ts b/src/app/hooks/customValidation.ts index 3b11b721..96009496 100644 --- a/src/app/hooks/customValidation.ts +++ b/src/app/hooks/customValidation.ts @@ -1,5 +1,6 @@ import { Errors, Hook, relativePath } from '@mcschema/core' import { BlockStateRegistry } from '../App' +import { getFilterKey } from './getFilterKey' import { walk } from './walk' export const customValidation: Hook<[any, Errors], void> = walk<[Errors]>({ @@ -32,7 +33,18 @@ export const customValidation: Hook<[any, Errors], void> = walk<[Errors]>({ number() {}, - object() {}, + object({ node, getActiveFields }, path, value) { + let activeFields = getActiveFields(path) + const filterKey = path.modelArr.length === 0 ? null : node.hook(getFilterKey, path, path) + const visibleKeys = Object.keys(activeFields) + .filter(k => filterKey !== k) + .filter(k => activeFields[k].enabled(path)) + if (visibleKeys.length === 1 && activeFields[visibleKeys[0]].type(path.push(visibleKeys[0])) === 'object') { + if (activeFields[visibleKeys[0]].optional() && JSON.stringify(value[visibleKeys[0]]) === '{}') { + path.push(visibleKeys[0]).set(undefined) + } + } + }, string() {} }) diff --git a/src/app/hooks/renderHtml.ts b/src/app/hooks/renderHtml.ts index 178c48ad..4ae634c2 100644 --- a/src/app/hooks/renderHtml.ts +++ b/src/app/hooks/renderHtml.ts @@ -164,7 +164,7 @@ export const renderHtml: Hook<[any, Mounter], [string, string, string]> = { return ['', ``, ''] }, - object({ node, getActiveFields, getChildModelPath, filter }, path, value, mounter) { + object({ node, getActiveFields, getChildModelPath }, path, value, mounter) { let prefix = '' if (node.optional()) { if (value === undefined) { @@ -179,15 +179,21 @@ export const renderHtml: Hook<[any, Mounter], [string, string, string]> = { const activeFields = getActiveFields(path) const activeKeys = Object.keys(activeFields) const filterKey = path.modelArr.length === 0 ? null : node.hook(getFilterKey, path, path) - if (filterKey) { + if (filterKey && !(activeFields[filterKey].hidden && activeFields[filterKey].hidden())) { + prefix += error(path.push(filterKey), mounter) + prefix += help(path.push(filterKey), mounter) suffix += activeFields[filterKey].hook(this, path.push(filterKey), value[filterKey], mounter)[1] } - body = (App.treeMinimized.get() + const visibleKeys = (App.treeMinimized.get() ? activeKeys.filter(k => value[k] !== undefined) : activeKeys) .filter(k => filterKey !== k) .filter(k => activeFields[k].enabled(path)) - .map(k => { + if (visibleKeys.length === 1 && activeFields[visibleKeys[0]].type(path.push(visibleKeys[0])) === 'object') { + const newValue = value[visibleKeys[0]] ?? {} + body = activeFields[visibleKeys[0]].hook(this, path.push(visibleKeys[0]), newValue, mounter)[2] + } else { + body = visibleKeys.map(k => { const field = activeFields[k] const childPath = getChildModelPath(path, k) const context = childPath.getContext().join('.') @@ -196,7 +202,7 @@ export const renderHtml: Hook<[any, Mounter], [string, string, string]> = { const category = field.category(childPath) const [cPrefix, cSuffix, cBody] = field.hook(this, childPath, value[k], mounter) - return `
+ return `
${error(childPath, mounter)} ${help(childPath, mounter)} @@ -210,6 +216,7 @@ export const renderHtml: Hook<[any, Mounter], [string, string, string]> = {
` }) .join('') + } } suffix += node.hook(suffixInjector, path, mounter) || '' return ['', prefix + suffix, body] diff --git a/src/styles/nodes.css b/src/styles/nodes.css index ae048ed4..2519c247 100644 --- a/src/styles/nodes.css +++ b/src/styles/nodes.css @@ -126,7 +126,7 @@ margin-right: -1px; } -.object-node > .node-header > *:first-child, +.object-node:not(.no-body) > .node-header > *:first-child, .map-node > .node-header > *:first-child, .list-node > .node-header > *:first-child { border-top-left-radius: 8px; @@ -341,6 +341,7 @@ span.menu-item { .node-entry > .object-node[data-category] > .node-header > .node-icon + *, .node-entry > .object-node[data-category] > .node-header > *:first-child { border-top-left-radius: 0; + border-bottom-left-radius: 0; border-left: none; }