From e41c15dead3d38efeb7737cfd8b9151ff4ec8e03 Mon Sep 17 00:00:00 2001 From: Krasimir Chobantonov Date: Tue, 12 Aug 2025 13:35:27 -0400 Subject: [PATCH 1/6] preserve the form data so when we update the additionalErrors the data is not reset to the initial state --- packages/vue-vuetify/dev/views/ExampleView.vue | 1 - packages/vue/src/components/JsonForms.vue | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/vue-vuetify/dev/views/ExampleView.vue b/packages/vue-vuetify/dev/views/ExampleView.vue index e4274ab3d1..ff18efe564 100644 --- a/packages/vue-vuetify/dev/views/ExampleView.vue +++ b/packages/vue-vuetify/dev/views/ExampleView.vue @@ -91,7 +91,6 @@ const onChange = (event: JsonFormsChangeEvent): void => { monaco.Uri.parse(toDataUri(props.example.name)), event.data !== undefined ? JSON.stringify(event.data, null, 2) : '', ); - state.data = event.data; } errors.value = event.errors; }; diff --git a/packages/vue/src/components/JsonForms.vue b/packages/vue/src/components/JsonForms.vue index d21863e574..fb17a5e7d7 100644 --- a/packages/vue/src/components/JsonForms.vue +++ b/packages/vue/src/components/JsonForms.vue @@ -251,6 +251,9 @@ export default defineComponent({ ); }, eventToEmit(newEvent) { + // update the data so if we change the additionalErrors this won't reset the form data + this.dataToUse = newEvent.data; + this.$emit('change', newEvent); }, i18n: { From d5218b15879ab69274c3e81b735737f0d33c04b7 Mon Sep 17 00:00:00 2001 From: Krasimir Chobantonov Date: Sat, 23 Aug 2025 18:09:42 -0400 Subject: [PATCH 2/6] also update the schema and uischema when they depend on the data and the data is changed --- packages/vue/src/components/JsonForms.vue | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/packages/vue/src/components/JsonForms.vue b/packages/vue/src/components/JsonForms.vue index fb17a5e7d7..59b791641a 100644 --- a/packages/vue/src/components/JsonForms.vue +++ b/packages/vue/src/components/JsonForms.vue @@ -212,6 +212,19 @@ export default defineComponent({ }, data(newData) { this.dataToUse = newData; + + if (!this.schema) { + const generatorData = isObject(newData) ? newData : {}; + this.schemaToUse = Generate.jsonSchema(generatorData); + if (!this.uischema) { + this.uischemaToUse = Generate.uiSchema( + this.schemaToUse, + undefined, + undefined, + this.schemaToUse + ); + } + } }, renderers(newRenderers) { this.jsonforms.renderers = newRenderers; From 0b979c0e98396b02a61a1d6585f36bd7e83e56ac Mon Sep 17 00:00:00 2001 From: Krasimir Chobantonov Date: Sat, 23 Aug 2025 19:47:46 -0400 Subject: [PATCH 3/6] properly generate schema in case when the data is not an object but simple type like number, string, array and etc. --- packages/core/src/generators/schema.ts | 2 +- packages/vue/src/components/JsonForms.vue | 15 +++------------ 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/packages/core/src/generators/schema.ts b/packages/core/src/generators/schema.ts index f3b1d2324b..2de7ef0a3c 100644 --- a/packages/core/src/generators/schema.ts +++ b/packages/core/src/generators/schema.ts @@ -177,5 +177,5 @@ export const generateJsonSchema = ( const gen = new Gen(findOption); - return gen.schemaObject(instance); + return gen.property(instance); }; diff --git a/packages/vue/src/components/JsonForms.vue b/packages/vue/src/components/JsonForms.vue index 59b791641a..e506123d9a 100644 --- a/packages/vue/src/components/JsonForms.vue +++ b/packages/vue/src/components/JsonForms.vue @@ -33,12 +33,6 @@ import DispatchRenderer from './DispatchRenderer.vue'; import type Ajv from 'ajv'; import type { ErrorObject } from 'ajv'; -// TODO fix @typescript-eslint/ban-types -// eslint-disable-next-line @typescript-eslint/ban-types -const isObject = (elem: any): elem is Object => { - return elem && typeof elem === 'object'; -}; - const EMPTY: ErrorObject[] = reactive([]); export default defineComponent({ @@ -124,9 +118,8 @@ export default defineComponent({ emits: ['change'], data() { const dataToUse = this.data; - const generatorData = isObject(dataToUse) ? dataToUse : {}; const schemaToUse: JsonSchema = - this.schema ?? Generate.jsonSchema(generatorData); + this.schema ?? Generate.jsonSchema(dataToUse); const uischemaToUse = this.uischema ?? Generate.uiSchema(schemaToUse, undefined, undefined, schemaToUse); @@ -189,8 +182,7 @@ export default defineComponent({ }, watch: { schema(newSchema) { - const generatorData = isObject(this.data) ? this.data : {}; - this.schemaToUse = newSchema ?? Generate.jsonSchema(generatorData); + this.schemaToUse = newSchema ?? Generate.jsonSchema(this.data); if (!this.uischema) { this.uischemaToUse = Generate.uiSchema( this.schemaToUse, @@ -214,8 +206,7 @@ export default defineComponent({ this.dataToUse = newData; if (!this.schema) { - const generatorData = isObject(newData) ? newData : {}; - this.schemaToUse = Generate.jsonSchema(generatorData); + this.schemaToUse = Generate.jsonSchema(newData); if (!this.uischema) { this.uischemaToUse = Generate.uiSchema( this.schemaToUse, From ebe262b137ba38e83aa61c0f4db148b362a89796 Mon Sep 17 00:00:00 2001 From: Krasimir Chobantonov Date: Sat, 23 Aug 2025 23:43:02 -0400 Subject: [PATCH 4/6] always return valid UISchemaElement, in case of empty schema this was returning null --- packages/core/src/generators/uischema.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/generators/uischema.ts b/packages/core/src/generators/uischema.ts index 8e5eb252a5..d394ee4276 100644 --- a/packages/core/src/generators/uischema.ts +++ b/packages/core/src/generators/uischema.ts @@ -138,7 +138,7 @@ const generateUISchema = ( const types = deriveTypes(jsonSchema); if (types.length === 0) { - return null; + return createLayout('VerticalLayout'); } if (types.length > 1) { From 51aa0bc1877361fb624dce5bd007eff983b79483 Mon Sep 17 00:00:00 2001 From: Krasimir Chobantonov Date: Sun, 24 Aug 2025 00:16:58 -0400 Subject: [PATCH 5/6] revert back the ability to return null from the generate but default to non null uischema in JsonForms --- packages/core/src/generators/uischema.ts | 2 +- packages/vue/src/components/JsonForms.vue | 36 ++++++++--------------- 2 files changed, 14 insertions(+), 24 deletions(-) diff --git a/packages/core/src/generators/uischema.ts b/packages/core/src/generators/uischema.ts index d394ee4276..8e5eb252a5 100644 --- a/packages/core/src/generators/uischema.ts +++ b/packages/core/src/generators/uischema.ts @@ -138,7 +138,7 @@ const generateUISchema = ( const types = deriveTypes(jsonSchema); if (types.length === 0) { - return createLayout('VerticalLayout'); + return null; } if (types.length > 1) { diff --git a/packages/vue/src/components/JsonForms.vue b/packages/vue/src/components/JsonForms.vue index e506123d9a..c7fbc16e6a 100644 --- a/packages/vue/src/components/JsonForms.vue +++ b/packages/vue/src/components/JsonForms.vue @@ -26,6 +26,7 @@ import { defaultMiddleware, Middleware, JsonFormsSubStates, + Layout, } from '@jsonforms/core'; import { JsonFormsChangeEvent, MaybeReadonly } from '../types'; import DispatchRenderer from './DispatchRenderer.vue'; @@ -35,6 +36,14 @@ import type { ErrorObject } from 'ajv'; const EMPTY: ErrorObject[] = reactive([]); +const createDefaultLayout = (): Layout => ({ + type: 'VerticalLayout', + elements: [], +}); +const generateUISchema = (schema: JsonSchema) => + Generate.uiSchema(schema, undefined, undefined, schema) ?? + createDefaultLayout(); + export default defineComponent({ name: 'JsonForms', components: { @@ -120,9 +129,7 @@ export default defineComponent({ const dataToUse = this.data; const schemaToUse: JsonSchema = this.schema ?? Generate.jsonSchema(dataToUse); - const uischemaToUse = - this.uischema ?? - Generate.uiSchema(schemaToUse, undefined, undefined, schemaToUse); + const uischemaToUse = this.uischema ?? generateUISchema(schemaToUse); const initCore = (): JsonFormsCore => { const initialCore = { data: dataToUse, @@ -184,23 +191,11 @@ export default defineComponent({ schema(newSchema) { this.schemaToUse = newSchema ?? Generate.jsonSchema(this.data); if (!this.uischema) { - this.uischemaToUse = Generate.uiSchema( - this.schemaToUse, - undefined, - undefined, - this.schemaToUse - ); + this.uischemaToUse = generateUISchema(this.schemaToUse); } }, uischema(newUischema) { - this.uischemaToUse = - newUischema ?? - Generate.uiSchema( - this.schemaToUse, - undefined, - undefined, - this.schemaToUse - ); + this.uischemaToUse = newUischema ?? generateUISchema(this.schemaToUse); }, data(newData) { this.dataToUse = newData; @@ -208,12 +203,7 @@ export default defineComponent({ if (!this.schema) { this.schemaToUse = Generate.jsonSchema(newData); if (!this.uischema) { - this.uischemaToUse = Generate.uiSchema( - this.schemaToUse, - undefined, - undefined, - this.schemaToUse - ); + this.uischemaToUse = generateUISchema(this.schemaToUse); } } }, From b27ce7ff7b98bbc8398b1799d2c95cf46797649d Mon Sep 17 00:00:00 2001 From: Krasimir Chobantonov Date: Fri, 5 Sep 2025 13:26:56 -0400 Subject: [PATCH 6/6] only for undefined use emtpy data for others the core can handle those --- packages/vue/src/components/JsonForms.vue | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/vue/src/components/JsonForms.vue b/packages/vue/src/components/JsonForms.vue index c7fbc16e6a..cb0781bb8f 100644 --- a/packages/vue/src/components/JsonForms.vue +++ b/packages/vue/src/components/JsonForms.vue @@ -126,7 +126,7 @@ export default defineComponent({ }, emits: ['change'], data() { - const dataToUse = this.data; + const dataToUse = this.data === undefined ? {} : this.data; const schemaToUse: JsonSchema = this.schema ?? Generate.jsonSchema(dataToUse); const uischemaToUse = this.uischema ?? generateUISchema(schemaToUse); @@ -189,7 +189,7 @@ export default defineComponent({ }, watch: { schema(newSchema) { - this.schemaToUse = newSchema ?? Generate.jsonSchema(this.data); + this.schemaToUse = newSchema ?? Generate.jsonSchema(this.dataToUse); if (!this.uischema) { this.uischemaToUse = generateUISchema(this.schemaToUse); } @@ -198,10 +198,10 @@ export default defineComponent({ this.uischemaToUse = newUischema ?? generateUISchema(this.schemaToUse); }, data(newData) { - this.dataToUse = newData; + this.dataToUse = newData === undefined ? {} : newData; if (!this.schema) { - this.schemaToUse = Generate.jsonSchema(newData); + this.schemaToUse = Generate.jsonSchema(this.dataToUse); if (!this.uischema) { this.uischemaToUse = generateUISchema(this.schemaToUse); }