@siliconst/metaui 1.4.9 → 1.4.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/package.json +1 -1
  2. package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost-dbg.js +10 -0
  3. package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost-dbg.js.map +1 -1
  4. package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost.d.ts.map +1 -1
  5. package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost.js +1 -1
  6. package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost.js.map +1 -1
  7. package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost.ts +11 -0
  8. package/src/nz/co/siliconst/ui5/metaui/core/Engine-dbg.js +2 -0
  9. package/src/nz/co/siliconst/ui5/metaui/core/Engine-dbg.js.map +1 -1
  10. package/src/nz/co/siliconst/ui5/metaui/core/Engine.d.ts +2 -0
  11. package/src/nz/co/siliconst/ui5/metaui/core/Engine.d.ts.map +1 -1
  12. package/src/nz/co/siliconst/ui5/metaui/core/Engine.js.map +1 -1
  13. package/src/nz/co/siliconst/ui5/metaui/core/Engine.ts +3 -0
  14. package/src/nz/co/siliconst/ui5/metaui/layouts/TableLayout-dbg.js +10 -0
  15. package/src/nz/co/siliconst/ui5/metaui/layouts/TableLayout-dbg.js.map +1 -1
  16. package/src/nz/co/siliconst/ui5/metaui/layouts/TableLayout.d.ts.map +1 -1
  17. package/src/nz/co/siliconst/ui5/metaui/layouts/TableLayout.js +1 -1
  18. package/src/nz/co/siliconst/ui5/metaui/layouts/TableLayout.js.map +1 -1
  19. package/src/nz/co/siliconst/ui5/metaui/layouts/TableLayout.ts +10 -0
  20. package/src/nz/co/siliconst/ui5/metaui/library-preload.js +6 -6
  21. package/src/nz/co/siliconst/ui5/metaui/library-preload.js.map +1 -1
  22. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ArrayPlugin-dbg.js +6 -0
  23. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ArrayPlugin-dbg.js.map +1 -1
  24. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ArrayPlugin.d.ts.map +1 -1
  25. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ArrayPlugin.js +1 -1
  26. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ArrayPlugin.js.map +1 -1
  27. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ArrayPlugin.ts +6 -0
  28. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CodeEditorPlugin-dbg.js +5 -2
  29. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CodeEditorPlugin-dbg.js.map +1 -1
  30. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CodeEditorPlugin.d.ts.map +1 -1
  31. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CodeEditorPlugin.js +1 -1
  32. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CodeEditorPlugin.js.map +1 -1
  33. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CodeEditorPlugin.ts +5 -2
  34. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ObjectPlugin-dbg.js +6 -0
  35. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ObjectPlugin-dbg.js.map +1 -1
  36. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ObjectPlugin.d.ts.map +1 -1
  37. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ObjectPlugin.js +1 -1
  38. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ObjectPlugin.js.map +1 -1
  39. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ObjectPlugin.ts +6 -0
  40. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TextAreaPlugin-dbg.js +39 -3
  41. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TextAreaPlugin-dbg.js.map +1 -1
  42. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TextAreaPlugin.d.ts +4 -0
  43. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TextAreaPlugin.d.ts.map +1 -1
  44. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TextAreaPlugin.js +1 -1
  45. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TextAreaPlugin.js.map +1 -1
  46. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TextAreaPlugin.ts +40 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@siliconst/metaui",
3
- "version": "1.4.9",
3
+ "version": "1.4.10",
4
4
  "description": "Dynamic Metadata UI5 Engine",
5
5
  "author": "SiliconStreetDev1",
6
6
  "license": "MIT",
@@ -169,6 +169,16 @@ sap.ui.define(["sap/ui/core/Control", "./host/GeneratorHost", "../utils/Logger",
169
169
  */
170
170
  initODataDelegate: function _initODataDelegate() {
171
171
  if (!this.odataDelegate) {
172
+ // Guard: If the user explicitly bound dataJson, do not steal the context.
173
+ if (this.getBindingInfo("dataJson")) {
174
+ return;
175
+ }
176
+
177
+ // Guard: If the user explicitly bound 'data' to a specific property path, do not steal the context.
178
+ const dataBinding = this.getBindingInfo("data");
179
+ if (dataBinding && dataBinding.path && dataBinding.path !== "") {
180
+ return;
181
+ }
172
182
  const oContext = this.getBindingContext("odata") || this.getBindingContext();
173
183
  if (oContext) {
174
184
  Logger.debug("[MetaUI DynamicHost]", `Context found for delegate initialization: ${oContext.getPath()}`, "DynamicHost");
@@ -1 +1 @@
1
- {"version":3,"file":"DynamicHost-dbg.js","names":["GeneratorHost","_interopRequireDefault","__GeneratorHost","Logger","___utils_Logger","ODataDelegate","___host_delegates_ODataDelegate","DynamicHost","Control","extend","constructor","prototype","apply","arguments","_innerHost","odataDelegate","_initializedInner","renderer","apiVersion","render","rm","control","openStart","style","openEnd","content","getAggregation","renderControl","close","metadata","properties","schemaDefinition","type","defaultValue","data","bindable","dataJson","liveUpdate","isValid","useMessageManager","modelName","debugMode","editable","aggregations","_content","multiple","visibility","events","beforeSubmit","parameters","payload","addError","preventDefault","submit","payloadJson","cancel","fieldChange","fieldPath","value","validationStateChanged","validationError","message","validationSuccess","initODataDelegate","_initODataDelegate","oContext","getBindingContext","debug","getPath","requestObject","syncToEngine","Object","keys","setBindingContext","_setBindingContext","sModelName","Control.prototype.setBindingContext.call","bindElement","_bindElement","vPath","mParameters","Control.prototype.bindElement.call","model","undefined","oBinding","getElementBinding","attachChange","onBeforeRendering","_onBeforeRendering","schema","getProperty","hasSchema","hasData","props","getMetadata","getProperties","propName","val","Control.prototype.getProperty.call","setProperty","setAggregation","getEvents","eventName","attachEvent","oEvent","params","getParameters","Control.prototype.setProperty.call","str","JSON","stringify","handleFieldChange","fireEvent","_setProperty","propertyName","suppressInvalidate","openInDialog","_openInDialog","title","submitButtonText","cancelButtonText","triggerSubmit","_triggerSubmit","_getProperty"],"sources":["DynamicHost.ts"],"sourcesContent":["import Control from \"sap/ui/core/Control\";\nimport RenderManager from \"sap/ui/core/RenderManager\";\nimport GeneratorHost from \"./host/GeneratorHost\";\nimport { Logger } from \"../utils/Logger\";\nimport { ODataDelegate } from \"./host/delegates/ODataDelegate\";\nimport ODataV4Context from \"sap/ui/model/odata/v4/Context\";\n\n/**\n * A transparent wrapper control (Facade) that automatically chooses between Explicit Schema Mode \n * and Inference Mode based on the presence of a 'schemaDefinition'.\n * \n * This maintains total architectural separation of the modes without forcing developers to \n * use different XML tags.\n * \n * @namespace nz.co.siliconst.ui5.metaui.controls\n */\nexport default class DynamicHost extends Control {\n private _innerHost: GeneratorHost | null = null;\n private odataDelegate: ODataDelegate | null = null;\n private _initializedInner: boolean = false;\n\n static readonly metadata = {\n properties: {\n schemaDefinition: { type: \"any\", defaultValue: null },\n data: { type: \"object\", defaultValue: null, bindable: \"bindable\" },\n dataJson: { type: \"string\", defaultValue: null, bindable: \"bindable\" },\n liveUpdate: { type: \"boolean\", defaultValue: false },\n isValid: { type: \"boolean\", defaultValue: true },\n useMessageManager: { type: \"boolean\", defaultValue: false },\n modelName: { type: \"string\", defaultValue: \"meta\" },\n debugMode: { type: \"boolean\", defaultValue: false },\n editable: { type: \"boolean\", defaultValue: true }\n },\n aggregations: {\n _content: { type: \"sap.ui.core.Control\", multiple: false, visibility: \"hidden\" }\n },\n events: {\n beforeSubmit: {\n parameters: {\n payload: { type: \"object\" },\n addError: { type: \"function\" },\n preventDefault: { type: \"function\" }\n }\n },\n submit: {\n parameters: {\n payload: { type: \"object\" },\n payloadJson: { type: \"string\" }\n }\n },\n cancel: {},\n fieldChange: {\n parameters: {\n fieldPath: { type: \"string\" },\n value: { type: \"any\" },\n payload: { type: \"object\" },\n isValid: { type: \"boolean\" }\n }\n },\n validationStateChanged: { parameters: { isValid: { type: \"boolean\" } } },\n validationError: { parameters: { fieldPath: { type: \"string\" }, message: { type: \"string\" } } },\n validationSuccess: { parameters: { fieldPath: { type: \"string\" } } }\n }\n };\n\n static renderer = {\n apiVersion: 2,\n render(rm: RenderManager, control: DynamicHost) {\n rm.openStart(\"div\", control);\n rm.style(\"width\", \"100%\");\n rm.style(\"height\", \"100%\");\n rm.openEnd();\n\n const content = control.getAggregation(\"_content\") as Control;\n if (content) {\n rm.renderControl(content);\n }\n\n rm.close(\"div\");\n }\n };\n\n /**\n * Internal reference to the generated inner host instance.\n * @private\n */\n private _innerHost: GeneratorHost | null = null;\n \n /**\n * Flag indicating if the inner host has been initialized.\n * @private\n */\n private _initializedInner: boolean = false;\n\n /**\n * Initializes the OData Delegate if an OData context is detected.\n * This allows DynamicHost to seamlessly synchronize metadata and properties from an OData model.\n * @private\n */\n private initODataDelegate(): void {\n if (!this.odataDelegate) {\n const oContext = this.getBindingContext(\"odata\") || this.getBindingContext();\n if (oContext) {\n Logger.debug(\"[MetaUI DynamicHost]\", `Context found for delegate initialization: ${oContext.getPath()}`, \"DynamicHost\");\n if (oContext && (oContext as ODataV4Context).requestObject && typeof (oContext as ODataV4Context).requestObject === \"function\") {\n Logger.debug(\"[MetaUI DynamicHost]\", `Context supports requestObject/getObject. Instantiating ODataDelegate.`, \"DynamicHost\");\n this.odataDelegate = new ODataDelegate(this, oContext as ODataV4Context);\n this.odataDelegate.syncToEngine();\n } else {\n Logger.debug(\"[MetaUI DynamicHost]\", `Context does NOT support requestObject/getObject! Keys: ${Object.keys(oContext)}`, \"DynamicHost\");\n }\n }\n }\n }\n\n /**\n * Standard UI5 method override.\n * Sets the binding context for the control and attempts to initialize the OData delegate\n * if the context points to an OData model.\n * \n * @param {sap.ui.model.Context | null | undefined} oContext The binding context object\n * @param {string} [sModelName] Optional model name\n * @returns {this} The control instance for chaining\n */\n public setBindingContext(oContext: sap.ui.model.Context | null | undefined, sModelName?: string): this {\n super.setBindingContext(oContext, sModelName);\n this.initODataDelegate();\n return this;\n }\n\n /**\n * Standard UI5 method override.\n * Binds the element to the given path and attaches a change listener to re-evaluate\n * the OData delegate when the element binding resolves.\n * \n * @param {string | Record<string, unknown>} vPath The binding path or configuration object\n * @param {object} [mParameters] Optional mapping parameters\n * @returns {this} Reference to this instance for chaining\n */\n public bindElement(vPath: string | Record<string, unknown>, mParameters?: object): this {\n super.bindElement(vPath, mParameters);\n const sModelName = typeof vPath === \"object\" ? vPath.model : undefined;\n const oBinding = this.getElementBinding(sModelName);\n if (oBinding) {\n oBinding.attachChange(() => {\n this.initODataDelegate();\n });\n }\n return this;\n }\n\n /**\n * Standard UI5 Lifecycle Hook.\n * Evaluates the initial properties and spawns the GeneratorHost.\n * It handles the complex lifecycle task of copying all bindings, raw properties, and event listeners \n * down to the inner host perfectly transparently.\n */\n public onBeforeRendering(): void {\n Logger.debug(\"[MetaUI DynamicHost]\", `onBeforeRendering called. _initializedInner: ${this._initializedInner}`, \"DynamicHost\");\n\n this.initODataDelegate();\n\n if (!this._initializedInner) {\n const schema = this.getProperty(\"schemaDefinition\");\n const dataJson = this.getProperty(\"dataJson\");\n const data = this.getProperty(\"data\");\n\n const hasSchema = !!schema;\n const hasData = !!dataJson || !!data;\n\n Logger.debug(\"[MetaUI DynamicHost]\", `Evaluating boot. hasSchema: ${hasSchema}, hasData: ${hasData}`, \"DynamicHost\");\n\n // Only boot if we have either a schema or some data to infer from\n if (hasSchema || hasData) {\n if (this.getProperty(\"debugMode\")) {\n Logger.debug(\"[MetaUI DynamicHost]\", `Booting inner host. hasSchema: ${hasSchema}, hasData: ${hasData}`, \"DynamicHost\");\n }\n // The architectural Facade router logic:\n // We've simplified this! We no longer use HostFactory or separate subclasses.\n // GeneratorHost is fully capable of inferring the schema if none is provided.\n this._innerHost = new GeneratorHost();\n\n // 1. Forward all static values to the spawned host BEFORE mounting.\n // Since we no longer use bindProperty, it's perfectly safe to set raw properties before mounting.\n const props = this.getMetadata().getProperties();\n for (const propName in props) {\n const val = super.getProperty(propName);\n if (val !== null && val !== undefined) {\n this._innerHost.setProperty(propName, val);\n }\n }\n\n // 2. Mount so it inherits models and triggers lifecycle.\n this.setAggregation(\"_content\", this._innerHost);\n\n // 3. Forward all event subscriptions.\n // By proxying the events upwards, the developer can subscribe to `<meta:DynamicHost submit=\"...\">` \n // and perfectly receive the inner host's submission event.\n const events = this.getMetadata().getEvents();\n for (const eventName in events) {\n this._innerHost.attachEvent(eventName, (oEvent: sap.ui.base.Event) => {\n // Natively push updated payload out to any bound Fiori Element properties.\n // Using super.setProperty prevents an infinite loop back down to _innerHost.\n if (eventName === \"submit\" || eventName === \"fieldChange\") {\n const params = oEvent.getParameters();\n if (params.payload) {\n super.setProperty(\"data\", params.payload, true);\n\n const str = params.payloadJson || JSON.stringify(params.payload, null, 2);\n super.setProperty(\"dataJson\", str, true);\n }\n if (eventName === \"fieldChange\" && this.odataDelegate) {\n this.odataDelegate.handleFieldChange(params.fieldPath, params.value);\n }\n }\n this.fireEvent(eventName, oEvent.getParameters());\n });\n }\n\n this._initializedInner = true;\n }\n }\n }\n\n /**\n * Overrides standard UI5 setProperty to act as a transparent proxy.\n * When a property is updated on the wrapper (either programmatically or via a binding update),\n * it instantly mirrors that value down to the inner instantiated host.\n */\n public setProperty(propertyName: string, value: unknown, suppressInvalidate?: boolean): this {\n if (propertyName === \"data\" || propertyName === \"dataJson\" || propertyName === \"schemaDefinition\") {\n if (this.getProperty(\"debugMode\")) {\n Logger.debug(\"[MetaUI DynamicHost]\", `Wrapper received setProperty: ${propertyName}`, \"DynamicHost\");\n }\n }\n super.setProperty(propertyName, value, suppressInvalidate);\n if (this._innerHost) {\n this._innerHost.setProperty(propertyName, value, suppressInvalidate);\n } else if (propertyName === \"data\" || propertyName === \"dataJson\" || propertyName === \"schemaDefinition\") {\n if (this.getProperty(\"debugMode\")) {\n Logger.debug(\"[MetaUI DynamicHost]\", `_innerHost not yet initialized when ${propertyName} was set. Booting will happen on next render.`, \"DynamicHost\");\n }\n }\n return this;\n }\n\n\n\n\n\n /**\n * Programmatic API support. Routes dialog commands down to the spawned inner host.\n * If the inner host has not booted yet, it forces initialization immediately.\n * \n * @param {string} [title=\"Form\"] The title of the dialog\n * @param {string} [submitButtonText=\"OK\"] The text for the primary action button\n * @param {string} [cancelButtonText=\"Cancel\"] The text for the cancel button\n */\n public openInDialog(title?: string, submitButtonText?: string, cancelButtonText?: string): void {\n if (!this._innerHost) {\n this.onBeforeRendering(); // Force init if they bypassed UI5 rendering\n }\n this._innerHost?.openInDialog(title, submitButtonText, cancelButtonText);\n }\n\n /**\n * Proxies submission triggering down to the instantiated generator host.\n * Evaluates the internal Engine validation suite and returns true if structurally sound.\n * \n * @returns {boolean} True if the internal payload passes schema validation, false otherwise.\n */\n public triggerSubmit(): boolean {\n if (!this._innerHost) {\n return false;\n }\n return this._innerHost.triggerSubmit();\n }\n\n /**\n * Overrides standard UI5 getProperty to transparently pull extracted data from the inner host.\n * Ensures that querying the DynamicHost facade for `data` always yields the freshest payload.\n * \n * @param {string} propertyName The name of the property to retrieve\n * @returns {unknown} The property value\n */\n public getProperty(propertyName: string): unknown {\n if (propertyName === \"outputData\") {\n propertyName = \"data\"; // Forward deprecated outputData to data\n }\n if (this._innerHost && (propertyName === \"data\" || propertyName === \"dataJson\")) {\n return this._innerHost.getProperty(propertyName);\n }\n return super.getProperty(propertyName);\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"DynamicHost-dbg.js","names":["GeneratorHost","_interopRequireDefault","__GeneratorHost","Logger","___utils_Logger","ODataDelegate","___host_delegates_ODataDelegate","DynamicHost","Control","extend","constructor","prototype","apply","arguments","_innerHost","odataDelegate","_initializedInner","renderer","apiVersion","render","rm","control","openStart","style","openEnd","content","getAggregation","renderControl","close","metadata","properties","schemaDefinition","type","defaultValue","data","bindable","dataJson","liveUpdate","isValid","useMessageManager","modelName","debugMode","editable","aggregations","_content","multiple","visibility","events","beforeSubmit","parameters","payload","addError","preventDefault","submit","payloadJson","cancel","fieldChange","fieldPath","value","validationStateChanged","validationError","message","validationSuccess","initODataDelegate","_initODataDelegate","getBindingInfo","dataBinding","path","oContext","getBindingContext","debug","getPath","requestObject","syncToEngine","Object","keys","setBindingContext","_setBindingContext","sModelName","Control.prototype.setBindingContext.call","bindElement","_bindElement","vPath","mParameters","Control.prototype.bindElement.call","model","undefined","oBinding","getElementBinding","attachChange","onBeforeRendering","_onBeforeRendering","schema","getProperty","hasSchema","hasData","props","getMetadata","getProperties","propName","val","Control.prototype.getProperty.call","setProperty","setAggregation","getEvents","eventName","attachEvent","oEvent","params","getParameters","Control.prototype.setProperty.call","str","JSON","stringify","handleFieldChange","fireEvent","_setProperty","propertyName","suppressInvalidate","openInDialog","_openInDialog","title","submitButtonText","cancelButtonText","triggerSubmit","_triggerSubmit","_getProperty"],"sources":["DynamicHost.ts"],"sourcesContent":["import Control from \"sap/ui/core/Control\";\nimport RenderManager from \"sap/ui/core/RenderManager\";\nimport GeneratorHost from \"./host/GeneratorHost\";\nimport { Logger } from \"../utils/Logger\";\nimport { ODataDelegate } from \"./host/delegates/ODataDelegate\";\nimport ODataV4Context from \"sap/ui/model/odata/v4/Context\";\n\n/**\n * A transparent wrapper control (Facade) that automatically chooses between Explicit Schema Mode \n * and Inference Mode based on the presence of a 'schemaDefinition'.\n * \n * This maintains total architectural separation of the modes without forcing developers to \n * use different XML tags.\n * \n * @namespace nz.co.siliconst.ui5.metaui.controls\n */\nexport default class DynamicHost extends Control {\n private _innerHost: GeneratorHost | null = null;\n private odataDelegate: ODataDelegate | null = null;\n private _initializedInner: boolean = false;\n\n static readonly metadata = {\n properties: {\n schemaDefinition: { type: \"any\", defaultValue: null },\n data: { type: \"object\", defaultValue: null, bindable: \"bindable\" },\n dataJson: { type: \"string\", defaultValue: null, bindable: \"bindable\" },\n liveUpdate: { type: \"boolean\", defaultValue: false },\n isValid: { type: \"boolean\", defaultValue: true },\n useMessageManager: { type: \"boolean\", defaultValue: false },\n modelName: { type: \"string\", defaultValue: \"meta\" },\n debugMode: { type: \"boolean\", defaultValue: false },\n editable: { type: \"boolean\", defaultValue: true }\n },\n aggregations: {\n _content: { type: \"sap.ui.core.Control\", multiple: false, visibility: \"hidden\" }\n },\n events: {\n beforeSubmit: {\n parameters: {\n payload: { type: \"object\" },\n addError: { type: \"function\" },\n preventDefault: { type: \"function\" }\n }\n },\n submit: {\n parameters: {\n payload: { type: \"object\" },\n payloadJson: { type: \"string\" }\n }\n },\n cancel: {},\n fieldChange: {\n parameters: {\n fieldPath: { type: \"string\" },\n value: { type: \"any\" },\n payload: { type: \"object\" },\n isValid: { type: \"boolean\" }\n }\n },\n validationStateChanged: { parameters: { isValid: { type: \"boolean\" } } },\n validationError: { parameters: { fieldPath: { type: \"string\" }, message: { type: \"string\" } } },\n validationSuccess: { parameters: { fieldPath: { type: \"string\" } } }\n }\n };\n\n static renderer = {\n apiVersion: 2,\n render(rm: RenderManager, control: DynamicHost) {\n rm.openStart(\"div\", control);\n rm.style(\"width\", \"100%\");\n rm.style(\"height\", \"100%\");\n rm.openEnd();\n\n const content = control.getAggregation(\"_content\") as Control;\n if (content) {\n rm.renderControl(content);\n }\n\n rm.close(\"div\");\n }\n };\n\n /**\n * Internal reference to the generated inner host instance.\n * @private\n */\n private _innerHost: GeneratorHost | null = null;\n \n /**\n * Flag indicating if the inner host has been initialized.\n * @private\n */\n private _initializedInner: boolean = false;\n\n /**\n * Initializes the OData Delegate if an OData context is detected.\n * This allows DynamicHost to seamlessly synchronize metadata and properties from an OData model.\n * @private\n */\n private initODataDelegate(): void {\n if (!this.odataDelegate) {\n // Guard: If the user explicitly bound dataJson, do not steal the context.\n if (this.getBindingInfo(\"dataJson\")) {\n return;\n }\n\n // Guard: If the user explicitly bound 'data' to a specific property path, do not steal the context.\n const dataBinding = this.getBindingInfo(\"data\") as any;\n if (dataBinding && dataBinding.path && dataBinding.path !== \"\") {\n return;\n }\n\n const oContext = this.getBindingContext(\"odata\") || this.getBindingContext();\n if (oContext) {\n Logger.debug(\"[MetaUI DynamicHost]\", `Context found for delegate initialization: ${oContext.getPath()}`, \"DynamicHost\");\n if (oContext && (oContext as ODataV4Context).requestObject && typeof (oContext as ODataV4Context).requestObject === \"function\") {\n Logger.debug(\"[MetaUI DynamicHost]\", `Context supports requestObject/getObject. Instantiating ODataDelegate.`, \"DynamicHost\");\n this.odataDelegate = new ODataDelegate(this, oContext as ODataV4Context);\n this.odataDelegate.syncToEngine();\n } else {\n Logger.debug(\"[MetaUI DynamicHost]\", `Context does NOT support requestObject/getObject! Keys: ${Object.keys(oContext)}`, \"DynamicHost\");\n }\n }\n }\n }\n\n /**\n * Standard UI5 method override.\n * Sets the binding context for the control and attempts to initialize the OData delegate\n * if the context points to an OData model.\n * \n * @param {sap.ui.model.Context | null | undefined} oContext The binding context object\n * @param {string} [sModelName] Optional model name\n * @returns {this} The control instance for chaining\n */\n public setBindingContext(oContext: sap.ui.model.Context | null | undefined, sModelName?: string): this {\n super.setBindingContext(oContext, sModelName);\n this.initODataDelegate();\n return this;\n }\n\n /**\n * Standard UI5 method override.\n * Binds the element to the given path and attaches a change listener to re-evaluate\n * the OData delegate when the element binding resolves.\n * \n * @param {string | Record<string, unknown>} vPath The binding path or configuration object\n * @param {object} [mParameters] Optional mapping parameters\n * @returns {this} Reference to this instance for chaining\n */\n public bindElement(vPath: string | Record<string, unknown>, mParameters?: object): this {\n super.bindElement(vPath, mParameters);\n const sModelName = typeof vPath === \"object\" ? vPath.model : undefined;\n const oBinding = this.getElementBinding(sModelName);\n if (oBinding) {\n oBinding.attachChange(() => {\n this.initODataDelegate();\n });\n }\n return this;\n }\n\n /**\n * Standard UI5 Lifecycle Hook.\n * Evaluates the initial properties and spawns the GeneratorHost.\n * It handles the complex lifecycle task of copying all bindings, raw properties, and event listeners \n * down to the inner host perfectly transparently.\n */\n public onBeforeRendering(): void {\n Logger.debug(\"[MetaUI DynamicHost]\", `onBeforeRendering called. _initializedInner: ${this._initializedInner}`, \"DynamicHost\");\n\n this.initODataDelegate();\n\n if (!this._initializedInner) {\n const schema = this.getProperty(\"schemaDefinition\");\n const dataJson = this.getProperty(\"dataJson\");\n const data = this.getProperty(\"data\");\n\n const hasSchema = !!schema;\n const hasData = !!dataJson || !!data;\n\n Logger.debug(\"[MetaUI DynamicHost]\", `Evaluating boot. hasSchema: ${hasSchema}, hasData: ${hasData}`, \"DynamicHost\");\n\n // Only boot if we have either a schema or some data to infer from\n if (hasSchema || hasData) {\n if (this.getProperty(\"debugMode\")) {\n Logger.debug(\"[MetaUI DynamicHost]\", `Booting inner host. hasSchema: ${hasSchema}, hasData: ${hasData}`, \"DynamicHost\");\n }\n // The architectural Facade router logic:\n // We've simplified this! We no longer use HostFactory or separate subclasses.\n // GeneratorHost is fully capable of inferring the schema if none is provided.\n this._innerHost = new GeneratorHost();\n\n // 1. Forward all static values to the spawned host BEFORE mounting.\n // Since we no longer use bindProperty, it's perfectly safe to set raw properties before mounting.\n const props = this.getMetadata().getProperties();\n for (const propName in props) {\n const val = super.getProperty(propName);\n if (val !== null && val !== undefined) {\n this._innerHost.setProperty(propName, val);\n }\n }\n\n // 2. Mount so it inherits models and triggers lifecycle.\n this.setAggregation(\"_content\", this._innerHost);\n\n // 3. Forward all event subscriptions.\n // By proxying the events upwards, the developer can subscribe to `<meta:DynamicHost submit=\"...\">` \n // and perfectly receive the inner host's submission event.\n const events = this.getMetadata().getEvents();\n for (const eventName in events) {\n this._innerHost.attachEvent(eventName, (oEvent: sap.ui.base.Event) => {\n // Natively push updated payload out to any bound Fiori Element properties.\n // Using super.setProperty prevents an infinite loop back down to _innerHost.\n if (eventName === \"submit\" || eventName === \"fieldChange\") {\n const params = oEvent.getParameters();\n if (params.payload) {\n super.setProperty(\"data\", params.payload, true);\n\n const str = params.payloadJson || JSON.stringify(params.payload, null, 2);\n super.setProperty(\"dataJson\", str, true);\n }\n if (eventName === \"fieldChange\" && this.odataDelegate) {\n this.odataDelegate.handleFieldChange(params.fieldPath, params.value);\n }\n }\n this.fireEvent(eventName, oEvent.getParameters());\n });\n }\n\n this._initializedInner = true;\n }\n }\n }\n\n /**\n * Overrides standard UI5 setProperty to act as a transparent proxy.\n * When a property is updated on the wrapper (either programmatically or via a binding update),\n * it instantly mirrors that value down to the inner instantiated host.\n */\n public setProperty(propertyName: string, value: unknown, suppressInvalidate?: boolean): this {\n if (propertyName === \"data\" || propertyName === \"dataJson\" || propertyName === \"schemaDefinition\") {\n if (this.getProperty(\"debugMode\")) {\n Logger.debug(\"[MetaUI DynamicHost]\", `Wrapper received setProperty: ${propertyName}`, \"DynamicHost\");\n }\n }\n super.setProperty(propertyName, value, suppressInvalidate);\n if (this._innerHost) {\n this._innerHost.setProperty(propertyName, value, suppressInvalidate);\n } else if (propertyName === \"data\" || propertyName === \"dataJson\" || propertyName === \"schemaDefinition\") {\n if (this.getProperty(\"debugMode\")) {\n Logger.debug(\"[MetaUI DynamicHost]\", `_innerHost not yet initialized when ${propertyName} was set. Booting will happen on next render.`, \"DynamicHost\");\n }\n }\n return this;\n }\n\n\n\n\n\n /**\n * Programmatic API support. Routes dialog commands down to the spawned inner host.\n * If the inner host has not booted yet, it forces initialization immediately.\n * \n * @param {string} [title=\"Form\"] The title of the dialog\n * @param {string} [submitButtonText=\"OK\"] The text for the primary action button\n * @param {string} [cancelButtonText=\"Cancel\"] The text for the cancel button\n */\n public openInDialog(title?: string, submitButtonText?: string, cancelButtonText?: string): void {\n if (!this._innerHost) {\n this.onBeforeRendering(); // Force init if they bypassed UI5 rendering\n }\n this._innerHost?.openInDialog(title, submitButtonText, cancelButtonText);\n }\n\n /**\n * Proxies submission triggering down to the instantiated generator host.\n * Evaluates the internal Engine validation suite and returns true if structurally sound.\n * \n * @returns {boolean} True if the internal payload passes schema validation, false otherwise.\n */\n public triggerSubmit(): boolean {\n if (!this._innerHost) {\n return false;\n }\n return this._innerHost.triggerSubmit();\n }\n\n /**\n * Overrides standard UI5 getProperty to transparently pull extracted data from the inner host.\n * Ensures that querying the DynamicHost facade for `data` always yields the freshest payload.\n * \n * @param {string} propertyName The name of the property to retrieve\n * @returns {unknown} The property value\n */\n public getProperty(propertyName: string): unknown {\n if (propertyName === \"outputData\") {\n propertyName = \"data\"; // Forward deprecated outputData to data\n }\n if (this._innerHost && (propertyName === \"data\" || propertyName === \"dataJson\")) {\n return this._innerHost.getProperty(propertyName);\n }\n return super.getProperty(propertyName);\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"DynamicHost.d.ts","sourceRoot":"../../../../../../../..","sources":["src/nz/co/siliconst/ui5/metaui/controls/DynamicHost.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,iDAAiD,CAAC;IACjE,OAAO,OAAO,MAAM,qBAAqB,CAAC;IAC1C,OAAO,aAAa,MAAM,2BAA2B,CAAC;IAMtD;;;;;;;;OAQG;IACH,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,OAAO;QAC5C,OAAO,CAAC,UAAU,CAA8B;QAChD,OAAO,CAAC,aAAa,CAA8B;QACnD,OAAO,CAAC,iBAAiB,CAAkB;QAE3C,MAAM,CAAC,QAAQ,CAAC,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA0CtB;QAEF,MAAM,CAAC,QAAQ;;uBAEA,aAAa,WAAW,WAAW;UAahD;QAEF;;;WAGG;QACH,OAAO,CAAC,UAAU,CAA8B;QAEhD;;;WAGG;QACH,OAAO,CAAC,iBAAiB,CAAkB;QAE3C;;;;WAIG;QACH,OAAO,CAAC,iBAAiB;QAgBzB;;;;;;;;WAQG;QACI,iBAAiB,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,GAAG,SAAS,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI;QAMtG;;;;;;;;WAQG;QACI,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI;QAYvF;;;;;WAKG;QACI,iBAAiB,IAAI,IAAI;QAmEhC;;;;WAIG;QACI,WAAW,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,kBAAkB,CAAC,EAAE,OAAO,GAAG,IAAI;QAqB5F;;;;;;;WAOG;QACI,YAAY,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI;QAO/F;;;;;WAKG;QACI,aAAa,IAAI,OAAO;QAO/B;;;;;;WAMG;QACI,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO;KASpD;CAEA"}
1
+ {"version":3,"file":"DynamicHost.d.ts","sourceRoot":"../../../../../../../..","sources":["src/nz/co/siliconst/ui5/metaui/controls/DynamicHost.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,iDAAiD,CAAC;IACjE,OAAO,OAAO,MAAM,qBAAqB,CAAC;IAC1C,OAAO,aAAa,MAAM,2BAA2B,CAAC;IAMtD;;;;;;;;OAQG;IACH,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,OAAO;QAC5C,OAAO,CAAC,UAAU,CAA8B;QAChD,OAAO,CAAC,aAAa,CAA8B;QACnD,OAAO,CAAC,iBAAiB,CAAkB;QAE3C,MAAM,CAAC,QAAQ,CAAC,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA0CtB;QAEF,MAAM,CAAC,QAAQ;;uBAEA,aAAa,WAAW,WAAW;UAahD;QAEF;;;WAGG;QACH,OAAO,CAAC,UAAU,CAA8B;QAEhD;;;WAGG;QACH,OAAO,CAAC,iBAAiB,CAAkB;QAE3C;;;;WAIG;QACH,OAAO,CAAC,iBAAiB;QA2BzB;;;;;;;;WAQG;QACI,iBAAiB,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,GAAG,SAAS,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI;QAMtG;;;;;;;;WAQG;QACI,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI;QAYvF;;;;;WAKG;QACI,iBAAiB,IAAI,IAAI;QAmEhC;;;;WAIG;QACI,WAAW,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,kBAAkB,CAAC,EAAE,OAAO,GAAG,IAAI;QAqB5F;;;;;;;WAOG;QACI,YAAY,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI;QAO/F;;;;;WAKG;QACI,aAAa,IAAI,OAAO;QAO/B;;;;;;WAMG;QACI,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO;KASpD;CAEA"}
@@ -1,2 +1,2 @@
1
- sap.ui.define(["sap/ui/core/Control","./host/GeneratorHost","../utils/Logger","./host/delegates/ODataDelegate"],function(t,e,n,i){"use strict";function a(t){return t&&t.__esModule&&typeof t.default!=="undefined"?t.default:t}const o=a(e);const s=n["Logger"];const r=i["ODataDelegate"];const l=t.extend("nz.co.siliconst.ui5.metaui.controls.DynamicHost",{constructor:function e(){t.prototype.constructor.apply(this,arguments);this._innerHost=null;this.odataDelegate=null;this._initializedInner=false;this._innerHost=null;this._initializedInner=false},renderer:{apiVersion:2,render(t,e){t.openStart("div",e);t.style("width","100%");t.style("height","100%");t.openEnd();const n=e.getAggregation("_content");if(n){t.renderControl(n)}t.close("div")}},metadata:{properties:{schemaDefinition:{type:"any",defaultValue:null},data:{type:"object",defaultValue:null,bindable:"bindable"},dataJson:{type:"string",defaultValue:null,bindable:"bindable"},liveUpdate:{type:"boolean",defaultValue:false},isValid:{type:"boolean",defaultValue:true},useMessageManager:{type:"boolean",defaultValue:false},modelName:{type:"string",defaultValue:"meta"},debugMode:{type:"boolean",defaultValue:false},editable:{type:"boolean",defaultValue:true}},aggregations:{_content:{type:"sap.ui.core.Control",multiple:false,visibility:"hidden"}},events:{beforeSubmit:{parameters:{payload:{type:"object"},addError:{type:"function"},preventDefault:{type:"function"}}},submit:{parameters:{payload:{type:"object"},payloadJson:{type:"string"}}},cancel:{},fieldChange:{parameters:{fieldPath:{type:"string"},value:{type:"any"},payload:{type:"object"},isValid:{type:"boolean"}}},validationStateChanged:{parameters:{isValid:{type:"boolean"}}},validationError:{parameters:{fieldPath:{type:"string"},message:{type:"string"}}},validationSuccess:{parameters:{fieldPath:{type:"string"}}}}},initODataDelegate:function t(){if(!this.odataDelegate){const t=this.getBindingContext("odata")||this.getBindingContext();if(t){s.debug("[MetaUI DynamicHost]",`Context found for delegate initialization: ${t.getPath()}`,"DynamicHost");if(t&&t.requestObject&&typeof t.requestObject==="function"){s.debug("[MetaUI DynamicHost]",`Context supports requestObject/getObject. Instantiating ODataDelegate.`,"DynamicHost");this.odataDelegate=new r(this,t);this.odataDelegate.syncToEngine()}else{s.debug("[MetaUI DynamicHost]",`Context does NOT support requestObject/getObject! Keys: ${Object.keys(t)}`,"DynamicHost")}}}},setBindingContext:function e(n,i){t.prototype.setBindingContext.call(this,n,i);this.initODataDelegate();return this},bindElement:function e(n,i){t.prototype.bindElement.call(this,n,i);const a=typeof n==="object"?n.model:undefined;const o=this.getElementBinding(a);if(o){o.attachChange(()=>{this.initODataDelegate()})}return this},onBeforeRendering:function e(){s.debug("[MetaUI DynamicHost]",`onBeforeRendering called. _initializedInner: ${this._initializedInner}`,"DynamicHost");this.initODataDelegate();if(!this._initializedInner){const e=this.getProperty("schemaDefinition");const n=this.getProperty("dataJson");const i=this.getProperty("data");const a=!!e;const r=!!n||!!i;s.debug("[MetaUI DynamicHost]",`Evaluating boot. hasSchema: ${a}, hasData: ${r}`,"DynamicHost");if(a||r){if(this.getProperty("debugMode")){s.debug("[MetaUI DynamicHost]",`Booting inner host. hasSchema: ${a}, hasData: ${r}`,"DynamicHost")}this._innerHost=new o;const e=this.getMetadata().getProperties();for(const n in e){const e=t.prototype.getProperty.call(this,n);if(e!==null&&e!==undefined){this._innerHost.setProperty(n,e)}}this.setAggregation("_content",this._innerHost);const n=this.getMetadata().getEvents();for(const e in n){this._innerHost.attachEvent(e,n=>{if(e==="submit"||e==="fieldChange"){const i=n.getParameters();if(i.payload){t.prototype.setProperty.call(this,"data",i.payload,true);const e=i.payloadJson||JSON.stringify(i.payload,null,2);t.prototype.setProperty.call(this,"dataJson",e,true)}if(e==="fieldChange"&&this.odataDelegate){this.odataDelegate.handleFieldChange(i.fieldPath,i.value)}}this.fireEvent(e,n.getParameters())})}this._initializedInner=true}}},setProperty:function e(n,i,a){if(n==="data"||n==="dataJson"||n==="schemaDefinition"){if(this.getProperty("debugMode")){s.debug("[MetaUI DynamicHost]",`Wrapper received setProperty: ${n}`,"DynamicHost")}}t.prototype.setProperty.call(this,n,i,a);if(this._innerHost){this._innerHost.setProperty(n,i,a)}else if(n==="data"||n==="dataJson"||n==="schemaDefinition"){if(this.getProperty("debugMode")){s.debug("[MetaUI DynamicHost]",`_innerHost not yet initialized when ${n} was set. Booting will happen on next render.`,"DynamicHost")}}return this},openInDialog:function t(e,n,i){if(!this._innerHost){this.onBeforeRendering()}this._innerHost?.openInDialog(e,n,i)},triggerSubmit:function t(){if(!this._innerHost){return false}return this._innerHost.triggerSubmit()},getProperty:function e(n){if(n==="outputData"){n="data"}if(this._innerHost&&(n==="data"||n==="dataJson")){return this._innerHost.getProperty(n)}return t.prototype.getProperty.call(this,n)}});return l});
1
+ sap.ui.define(["sap/ui/core/Control","./host/GeneratorHost","../utils/Logger","./host/delegates/ODataDelegate"],function(t,e,n,i){"use strict";function a(t){return t&&t.__esModule&&typeof t.default!=="undefined"?t.default:t}const o=a(e);const s=n["Logger"];const r=i["ODataDelegate"];const l=t.extend("nz.co.siliconst.ui5.metaui.controls.DynamicHost",{constructor:function e(){t.prototype.constructor.apply(this,arguments);this._innerHost=null;this.odataDelegate=null;this._initializedInner=false;this._innerHost=null;this._initializedInner=false},renderer:{apiVersion:2,render(t,e){t.openStart("div",e);t.style("width","100%");t.style("height","100%");t.openEnd();const n=e.getAggregation("_content");if(n){t.renderControl(n)}t.close("div")}},metadata:{properties:{schemaDefinition:{type:"any",defaultValue:null},data:{type:"object",defaultValue:null,bindable:"bindable"},dataJson:{type:"string",defaultValue:null,bindable:"bindable"},liveUpdate:{type:"boolean",defaultValue:false},isValid:{type:"boolean",defaultValue:true},useMessageManager:{type:"boolean",defaultValue:false},modelName:{type:"string",defaultValue:"meta"},debugMode:{type:"boolean",defaultValue:false},editable:{type:"boolean",defaultValue:true}},aggregations:{_content:{type:"sap.ui.core.Control",multiple:false,visibility:"hidden"}},events:{beforeSubmit:{parameters:{payload:{type:"object"},addError:{type:"function"},preventDefault:{type:"function"}}},submit:{parameters:{payload:{type:"object"},payloadJson:{type:"string"}}},cancel:{},fieldChange:{parameters:{fieldPath:{type:"string"},value:{type:"any"},payload:{type:"object"},isValid:{type:"boolean"}}},validationStateChanged:{parameters:{isValid:{type:"boolean"}}},validationError:{parameters:{fieldPath:{type:"string"},message:{type:"string"}}},validationSuccess:{parameters:{fieldPath:{type:"string"}}}}},initODataDelegate:function t(){if(!this.odataDelegate){if(this.getBindingInfo("dataJson")){return}const t=this.getBindingInfo("data");if(t&&t.path&&t.path!==""){return}const e=this.getBindingContext("odata")||this.getBindingContext();if(e){s.debug("[MetaUI DynamicHost]",`Context found for delegate initialization: ${e.getPath()}`,"DynamicHost");if(e&&e.requestObject&&typeof e.requestObject==="function"){s.debug("[MetaUI DynamicHost]",`Context supports requestObject/getObject. Instantiating ODataDelegate.`,"DynamicHost");this.odataDelegate=new r(this,e);this.odataDelegate.syncToEngine()}else{s.debug("[MetaUI DynamicHost]",`Context does NOT support requestObject/getObject! Keys: ${Object.keys(e)}`,"DynamicHost")}}}},setBindingContext:function e(n,i){t.prototype.setBindingContext.call(this,n,i);this.initODataDelegate();return this},bindElement:function e(n,i){t.prototype.bindElement.call(this,n,i);const a=typeof n==="object"?n.model:undefined;const o=this.getElementBinding(a);if(o){o.attachChange(()=>{this.initODataDelegate()})}return this},onBeforeRendering:function e(){s.debug("[MetaUI DynamicHost]",`onBeforeRendering called. _initializedInner: ${this._initializedInner}`,"DynamicHost");this.initODataDelegate();if(!this._initializedInner){const e=this.getProperty("schemaDefinition");const n=this.getProperty("dataJson");const i=this.getProperty("data");const a=!!e;const r=!!n||!!i;s.debug("[MetaUI DynamicHost]",`Evaluating boot. hasSchema: ${a}, hasData: ${r}`,"DynamicHost");if(a||r){if(this.getProperty("debugMode")){s.debug("[MetaUI DynamicHost]",`Booting inner host. hasSchema: ${a}, hasData: ${r}`,"DynamicHost")}this._innerHost=new o;const e=this.getMetadata().getProperties();for(const n in e){const e=t.prototype.getProperty.call(this,n);if(e!==null&&e!==undefined){this._innerHost.setProperty(n,e)}}this.setAggregation("_content",this._innerHost);const n=this.getMetadata().getEvents();for(const e in n){this._innerHost.attachEvent(e,n=>{if(e==="submit"||e==="fieldChange"){const i=n.getParameters();if(i.payload){t.prototype.setProperty.call(this,"data",i.payload,true);const e=i.payloadJson||JSON.stringify(i.payload,null,2);t.prototype.setProperty.call(this,"dataJson",e,true)}if(e==="fieldChange"&&this.odataDelegate){this.odataDelegate.handleFieldChange(i.fieldPath,i.value)}}this.fireEvent(e,n.getParameters())})}this._initializedInner=true}}},setProperty:function e(n,i,a){if(n==="data"||n==="dataJson"||n==="schemaDefinition"){if(this.getProperty("debugMode")){s.debug("[MetaUI DynamicHost]",`Wrapper received setProperty: ${n}`,"DynamicHost")}}t.prototype.setProperty.call(this,n,i,a);if(this._innerHost){this._innerHost.setProperty(n,i,a)}else if(n==="data"||n==="dataJson"||n==="schemaDefinition"){if(this.getProperty("debugMode")){s.debug("[MetaUI DynamicHost]",`_innerHost not yet initialized when ${n} was set. Booting will happen on next render.`,"DynamicHost")}}return this},openInDialog:function t(e,n,i){if(!this._innerHost){this.onBeforeRendering()}this._innerHost?.openInDialog(e,n,i)},triggerSubmit:function t(){if(!this._innerHost){return false}return this._innerHost.triggerSubmit()},getProperty:function e(n){if(n==="outputData"){n="data"}if(this._innerHost&&(n==="data"||n==="dataJson")){return this._innerHost.getProperty(n)}return t.prototype.getProperty.call(this,n)}});return l});
2
2
  //# sourceMappingURL=DynamicHost.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DynamicHost.js","names":["GeneratorHost","_interopRequireDefault","__GeneratorHost","Logger","___utils_Logger","ODataDelegate","___host_delegates_ODataDelegate","DynamicHost","Control","extend","constructor","prototype","apply","this","arguments","_innerHost","odataDelegate","_initializedInner","renderer","apiVersion","render","rm","control","openStart","style","openEnd","content","getAggregation","renderControl","close","metadata","properties","schemaDefinition","type","defaultValue","data","bindable","dataJson","liveUpdate","isValid","useMessageManager","modelName","debugMode","editable","aggregations","_content","multiple","visibility","events","beforeSubmit","parameters","payload","addError","preventDefault","submit","payloadJson","cancel","fieldChange","fieldPath","value","validationStateChanged","validationError","message","validationSuccess","initODataDelegate","_initODataDelegate","oContext","getBindingContext","debug","getPath","requestObject","syncToEngine","Object","keys","setBindingContext","_setBindingContext","sModelName","Control.prototype.setBindingContext.call","bindElement","_bindElement","vPath","mParameters","Control.prototype.bindElement.call","model","undefined","oBinding","getElementBinding","attachChange","onBeforeRendering","_onBeforeRendering","schema","getProperty","hasSchema","hasData","props","getMetadata","getProperties","propName","val","Control.prototype.getProperty.call","setProperty","setAggregation","getEvents","eventName","attachEvent","oEvent","params","getParameters","Control.prototype.setProperty.call","str","JSON","stringify","handleFieldChange","fireEvent","_setProperty","propertyName","suppressInvalidate","openInDialog","_openInDialog","title","submitButtonText","cancelButtonText","triggerSubmit","_triggerSubmit","_getProperty"],"sources":["DynamicHost.ts"],"sourcesContent":["import Control from \"sap/ui/core/Control\";\nimport RenderManager from \"sap/ui/core/RenderManager\";\nimport GeneratorHost from \"./host/GeneratorHost\";\nimport { Logger } from \"../utils/Logger\";\nimport { ODataDelegate } from \"./host/delegates/ODataDelegate\";\nimport ODataV4Context from \"sap/ui/model/odata/v4/Context\";\n\n/**\n * A transparent wrapper control (Facade) that automatically chooses between Explicit Schema Mode \n * and Inference Mode based on the presence of a 'schemaDefinition'.\n * \n * This maintains total architectural separation of the modes without forcing developers to \n * use different XML tags.\n * \n * @namespace nz.co.siliconst.ui5.metaui.controls\n */\nexport default class DynamicHost extends Control {\n private _innerHost: GeneratorHost | null = null;\n private odataDelegate: ODataDelegate | null = null;\n private _initializedInner: boolean = false;\n\n static readonly metadata = {\n properties: {\n schemaDefinition: { type: \"any\", defaultValue: null },\n data: { type: \"object\", defaultValue: null, bindable: \"bindable\" },\n dataJson: { type: \"string\", defaultValue: null, bindable: \"bindable\" },\n liveUpdate: { type: \"boolean\", defaultValue: false },\n isValid: { type: \"boolean\", defaultValue: true },\n useMessageManager: { type: \"boolean\", defaultValue: false },\n modelName: { type: \"string\", defaultValue: \"meta\" },\n debugMode: { type: \"boolean\", defaultValue: false },\n editable: { type: \"boolean\", defaultValue: true }\n },\n aggregations: {\n _content: { type: \"sap.ui.core.Control\", multiple: false, visibility: \"hidden\" }\n },\n events: {\n beforeSubmit: {\n parameters: {\n payload: { type: \"object\" },\n addError: { type: \"function\" },\n preventDefault: { type: \"function\" }\n }\n },\n submit: {\n parameters: {\n payload: { type: \"object\" },\n payloadJson: { type: \"string\" }\n }\n },\n cancel: {},\n fieldChange: {\n parameters: {\n fieldPath: { type: \"string\" },\n value: { type: \"any\" },\n payload: { type: \"object\" },\n isValid: { type: \"boolean\" }\n }\n },\n validationStateChanged: { parameters: { isValid: { type: \"boolean\" } } },\n validationError: { parameters: { fieldPath: { type: \"string\" }, message: { type: \"string\" } } },\n validationSuccess: { parameters: { fieldPath: { type: \"string\" } } }\n }\n };\n\n static renderer = {\n apiVersion: 2,\n render(rm: RenderManager, control: DynamicHost) {\n rm.openStart(\"div\", control);\n rm.style(\"width\", \"100%\");\n rm.style(\"height\", \"100%\");\n rm.openEnd();\n\n const content = control.getAggregation(\"_content\") as Control;\n if (content) {\n rm.renderControl(content);\n }\n\n rm.close(\"div\");\n }\n };\n\n /**\n * Internal reference to the generated inner host instance.\n * @private\n */\n private _innerHost: GeneratorHost | null = null;\n \n /**\n * Flag indicating if the inner host has been initialized.\n * @private\n */\n private _initializedInner: boolean = false;\n\n /**\n * Initializes the OData Delegate if an OData context is detected.\n * This allows DynamicHost to seamlessly synchronize metadata and properties from an OData model.\n * @private\n */\n private initODataDelegate(): void {\n if (!this.odataDelegate) {\n const oContext = this.getBindingContext(\"odata\") || this.getBindingContext();\n if (oContext) {\n Logger.debug(\"[MetaUI DynamicHost]\", `Context found for delegate initialization: ${oContext.getPath()}`, \"DynamicHost\");\n if (oContext && (oContext as ODataV4Context).requestObject && typeof (oContext as ODataV4Context).requestObject === \"function\") {\n Logger.debug(\"[MetaUI DynamicHost]\", `Context supports requestObject/getObject. Instantiating ODataDelegate.`, \"DynamicHost\");\n this.odataDelegate = new ODataDelegate(this, oContext as ODataV4Context);\n this.odataDelegate.syncToEngine();\n } else {\n Logger.debug(\"[MetaUI DynamicHost]\", `Context does NOT support requestObject/getObject! Keys: ${Object.keys(oContext)}`, \"DynamicHost\");\n }\n }\n }\n }\n\n /**\n * Standard UI5 method override.\n * Sets the binding context for the control and attempts to initialize the OData delegate\n * if the context points to an OData model.\n * \n * @param {sap.ui.model.Context | null | undefined} oContext The binding context object\n * @param {string} [sModelName] Optional model name\n * @returns {this} The control instance for chaining\n */\n public setBindingContext(oContext: sap.ui.model.Context | null | undefined, sModelName?: string): this {\n super.setBindingContext(oContext, sModelName);\n this.initODataDelegate();\n return this;\n }\n\n /**\n * Standard UI5 method override.\n * Binds the element to the given path and attaches a change listener to re-evaluate\n * the OData delegate when the element binding resolves.\n * \n * @param {string | Record<string, unknown>} vPath The binding path or configuration object\n * @param {object} [mParameters] Optional mapping parameters\n * @returns {this} Reference to this instance for chaining\n */\n public bindElement(vPath: string | Record<string, unknown>, mParameters?: object): this {\n super.bindElement(vPath, mParameters);\n const sModelName = typeof vPath === \"object\" ? vPath.model : undefined;\n const oBinding = this.getElementBinding(sModelName);\n if (oBinding) {\n oBinding.attachChange(() => {\n this.initODataDelegate();\n });\n }\n return this;\n }\n\n /**\n * Standard UI5 Lifecycle Hook.\n * Evaluates the initial properties and spawns the GeneratorHost.\n * It handles the complex lifecycle task of copying all bindings, raw properties, and event listeners \n * down to the inner host perfectly transparently.\n */\n public onBeforeRendering(): void {\n Logger.debug(\"[MetaUI DynamicHost]\", `onBeforeRendering called. _initializedInner: ${this._initializedInner}`, \"DynamicHost\");\n\n this.initODataDelegate();\n\n if (!this._initializedInner) {\n const schema = this.getProperty(\"schemaDefinition\");\n const dataJson = this.getProperty(\"dataJson\");\n const data = this.getProperty(\"data\");\n\n const hasSchema = !!schema;\n const hasData = !!dataJson || !!data;\n\n Logger.debug(\"[MetaUI DynamicHost]\", `Evaluating boot. hasSchema: ${hasSchema}, hasData: ${hasData}`, \"DynamicHost\");\n\n // Only boot if we have either a schema or some data to infer from\n if (hasSchema || hasData) {\n if (this.getProperty(\"debugMode\")) {\n Logger.debug(\"[MetaUI DynamicHost]\", `Booting inner host. hasSchema: ${hasSchema}, hasData: ${hasData}`, \"DynamicHost\");\n }\n // The architectural Facade router logic:\n // We've simplified this! We no longer use HostFactory or separate subclasses.\n // GeneratorHost is fully capable of inferring the schema if none is provided.\n this._innerHost = new GeneratorHost();\n\n // 1. Forward all static values to the spawned host BEFORE mounting.\n // Since we no longer use bindProperty, it's perfectly safe to set raw properties before mounting.\n const props = this.getMetadata().getProperties();\n for (const propName in props) {\n const val = super.getProperty(propName);\n if (val !== null && val !== undefined) {\n this._innerHost.setProperty(propName, val);\n }\n }\n\n // 2. Mount so it inherits models and triggers lifecycle.\n this.setAggregation(\"_content\", this._innerHost);\n\n // 3. Forward all event subscriptions.\n // By proxying the events upwards, the developer can subscribe to `<meta:DynamicHost submit=\"...\">` \n // and perfectly receive the inner host's submission event.\n const events = this.getMetadata().getEvents();\n for (const eventName in events) {\n this._innerHost.attachEvent(eventName, (oEvent: sap.ui.base.Event) => {\n // Natively push updated payload out to any bound Fiori Element properties.\n // Using super.setProperty prevents an infinite loop back down to _innerHost.\n if (eventName === \"submit\" || eventName === \"fieldChange\") {\n const params = oEvent.getParameters();\n if (params.payload) {\n super.setProperty(\"data\", params.payload, true);\n\n const str = params.payloadJson || JSON.stringify(params.payload, null, 2);\n super.setProperty(\"dataJson\", str, true);\n }\n if (eventName === \"fieldChange\" && this.odataDelegate) {\n this.odataDelegate.handleFieldChange(params.fieldPath, params.value);\n }\n }\n this.fireEvent(eventName, oEvent.getParameters());\n });\n }\n\n this._initializedInner = true;\n }\n }\n }\n\n /**\n * Overrides standard UI5 setProperty to act as a transparent proxy.\n * When a property is updated on the wrapper (either programmatically or via a binding update),\n * it instantly mirrors that value down to the inner instantiated host.\n */\n public setProperty(propertyName: string, value: unknown, suppressInvalidate?: boolean): this {\n if (propertyName === \"data\" || propertyName === \"dataJson\" || propertyName === \"schemaDefinition\") {\n if (this.getProperty(\"debugMode\")) {\n Logger.debug(\"[MetaUI DynamicHost]\", `Wrapper received setProperty: ${propertyName}`, \"DynamicHost\");\n }\n }\n super.setProperty(propertyName, value, suppressInvalidate);\n if (this._innerHost) {\n this._innerHost.setProperty(propertyName, value, suppressInvalidate);\n } else if (propertyName === \"data\" || propertyName === \"dataJson\" || propertyName === \"schemaDefinition\") {\n if (this.getProperty(\"debugMode\")) {\n Logger.debug(\"[MetaUI DynamicHost]\", `_innerHost not yet initialized when ${propertyName} was set. Booting will happen on next render.`, \"DynamicHost\");\n }\n }\n return this;\n }\n\n\n\n\n\n /**\n * Programmatic API support. Routes dialog commands down to the spawned inner host.\n * If the inner host has not booted yet, it forces initialization immediately.\n * \n * @param {string} [title=\"Form\"] The title of the dialog\n * @param {string} [submitButtonText=\"OK\"] The text for the primary action button\n * @param {string} [cancelButtonText=\"Cancel\"] The text for the cancel button\n */\n public openInDialog(title?: string, submitButtonText?: string, cancelButtonText?: string): void {\n if (!this._innerHost) {\n this.onBeforeRendering(); // Force init if they bypassed UI5 rendering\n }\n this._innerHost?.openInDialog(title, submitButtonText, cancelButtonText);\n }\n\n /**\n * Proxies submission triggering down to the instantiated generator host.\n * Evaluates the internal Engine validation suite and returns true if structurally sound.\n * \n * @returns {boolean} True if the internal payload passes schema validation, false otherwise.\n */\n public triggerSubmit(): boolean {\n if (!this._innerHost) {\n return false;\n }\n return this._innerHost.triggerSubmit();\n }\n\n /**\n * Overrides standard UI5 getProperty to transparently pull extracted data from the inner host.\n * Ensures that querying the DynamicHost facade for `data` always yields the freshest payload.\n * \n * @param {string} propertyName The name of the property to retrieve\n * @returns {unknown} The property value\n */\n public getProperty(propertyName: string): unknown {\n if (propertyName === \"outputData\") {\n propertyName = \"data\"; // Forward deprecated outputData to data\n }\n if (this._innerHost && (propertyName === \"data\" || propertyName === \"dataJson\")) {\n return this._innerHost.getProperty(propertyName);\n }\n return super.getProperty(propertyName);\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"DynamicHost.js","names":["GeneratorHost","_interopRequireDefault","__GeneratorHost","Logger","___utils_Logger","ODataDelegate","___host_delegates_ODataDelegate","DynamicHost","Control","extend","constructor","prototype","apply","this","arguments","_innerHost","odataDelegate","_initializedInner","renderer","apiVersion","render","rm","control","openStart","style","openEnd","content","getAggregation","renderControl","close","metadata","properties","schemaDefinition","type","defaultValue","data","bindable","dataJson","liveUpdate","isValid","useMessageManager","modelName","debugMode","editable","aggregations","_content","multiple","visibility","events","beforeSubmit","parameters","payload","addError","preventDefault","submit","payloadJson","cancel","fieldChange","fieldPath","value","validationStateChanged","validationError","message","validationSuccess","initODataDelegate","_initODataDelegate","getBindingInfo","dataBinding","path","oContext","getBindingContext","debug","getPath","requestObject","syncToEngine","Object","keys","setBindingContext","_setBindingContext","sModelName","Control.prototype.setBindingContext.call","bindElement","_bindElement","vPath","mParameters","Control.prototype.bindElement.call","model","undefined","oBinding","getElementBinding","attachChange","onBeforeRendering","_onBeforeRendering","schema","getProperty","hasSchema","hasData","props","getMetadata","getProperties","propName","val","Control.prototype.getProperty.call","setProperty","setAggregation","getEvents","eventName","attachEvent","oEvent","params","getParameters","Control.prototype.setProperty.call","str","JSON","stringify","handleFieldChange","fireEvent","_setProperty","propertyName","suppressInvalidate","openInDialog","_openInDialog","title","submitButtonText","cancelButtonText","triggerSubmit","_triggerSubmit","_getProperty"],"sources":["DynamicHost.ts"],"sourcesContent":["import Control from \"sap/ui/core/Control\";\nimport RenderManager from \"sap/ui/core/RenderManager\";\nimport GeneratorHost from \"./host/GeneratorHost\";\nimport { Logger } from \"../utils/Logger\";\nimport { ODataDelegate } from \"./host/delegates/ODataDelegate\";\nimport ODataV4Context from \"sap/ui/model/odata/v4/Context\";\n\n/**\n * A transparent wrapper control (Facade) that automatically chooses between Explicit Schema Mode \n * and Inference Mode based on the presence of a 'schemaDefinition'.\n * \n * This maintains total architectural separation of the modes without forcing developers to \n * use different XML tags.\n * \n * @namespace nz.co.siliconst.ui5.metaui.controls\n */\nexport default class DynamicHost extends Control {\n private _innerHost: GeneratorHost | null = null;\n private odataDelegate: ODataDelegate | null = null;\n private _initializedInner: boolean = false;\n\n static readonly metadata = {\n properties: {\n schemaDefinition: { type: \"any\", defaultValue: null },\n data: { type: \"object\", defaultValue: null, bindable: \"bindable\" },\n dataJson: { type: \"string\", defaultValue: null, bindable: \"bindable\" },\n liveUpdate: { type: \"boolean\", defaultValue: false },\n isValid: { type: \"boolean\", defaultValue: true },\n useMessageManager: { type: \"boolean\", defaultValue: false },\n modelName: { type: \"string\", defaultValue: \"meta\" },\n debugMode: { type: \"boolean\", defaultValue: false },\n editable: { type: \"boolean\", defaultValue: true }\n },\n aggregations: {\n _content: { type: \"sap.ui.core.Control\", multiple: false, visibility: \"hidden\" }\n },\n events: {\n beforeSubmit: {\n parameters: {\n payload: { type: \"object\" },\n addError: { type: \"function\" },\n preventDefault: { type: \"function\" }\n }\n },\n submit: {\n parameters: {\n payload: { type: \"object\" },\n payloadJson: { type: \"string\" }\n }\n },\n cancel: {},\n fieldChange: {\n parameters: {\n fieldPath: { type: \"string\" },\n value: { type: \"any\" },\n payload: { type: \"object\" },\n isValid: { type: \"boolean\" }\n }\n },\n validationStateChanged: { parameters: { isValid: { type: \"boolean\" } } },\n validationError: { parameters: { fieldPath: { type: \"string\" }, message: { type: \"string\" } } },\n validationSuccess: { parameters: { fieldPath: { type: \"string\" } } }\n }\n };\n\n static renderer = {\n apiVersion: 2,\n render(rm: RenderManager, control: DynamicHost) {\n rm.openStart(\"div\", control);\n rm.style(\"width\", \"100%\");\n rm.style(\"height\", \"100%\");\n rm.openEnd();\n\n const content = control.getAggregation(\"_content\") as Control;\n if (content) {\n rm.renderControl(content);\n }\n\n rm.close(\"div\");\n }\n };\n\n /**\n * Internal reference to the generated inner host instance.\n * @private\n */\n private _innerHost: GeneratorHost | null = null;\n \n /**\n * Flag indicating if the inner host has been initialized.\n * @private\n */\n private _initializedInner: boolean = false;\n\n /**\n * Initializes the OData Delegate if an OData context is detected.\n * This allows DynamicHost to seamlessly synchronize metadata and properties from an OData model.\n * @private\n */\n private initODataDelegate(): void {\n if (!this.odataDelegate) {\n // Guard: If the user explicitly bound dataJson, do not steal the context.\n if (this.getBindingInfo(\"dataJson\")) {\n return;\n }\n\n // Guard: If the user explicitly bound 'data' to a specific property path, do not steal the context.\n const dataBinding = this.getBindingInfo(\"data\") as any;\n if (dataBinding && dataBinding.path && dataBinding.path !== \"\") {\n return;\n }\n\n const oContext = this.getBindingContext(\"odata\") || this.getBindingContext();\n if (oContext) {\n Logger.debug(\"[MetaUI DynamicHost]\", `Context found for delegate initialization: ${oContext.getPath()}`, \"DynamicHost\");\n if (oContext && (oContext as ODataV4Context).requestObject && typeof (oContext as ODataV4Context).requestObject === \"function\") {\n Logger.debug(\"[MetaUI DynamicHost]\", `Context supports requestObject/getObject. Instantiating ODataDelegate.`, \"DynamicHost\");\n this.odataDelegate = new ODataDelegate(this, oContext as ODataV4Context);\n this.odataDelegate.syncToEngine();\n } else {\n Logger.debug(\"[MetaUI DynamicHost]\", `Context does NOT support requestObject/getObject! Keys: ${Object.keys(oContext)}`, \"DynamicHost\");\n }\n }\n }\n }\n\n /**\n * Standard UI5 method override.\n * Sets the binding context for the control and attempts to initialize the OData delegate\n * if the context points to an OData model.\n * \n * @param {sap.ui.model.Context | null | undefined} oContext The binding context object\n * @param {string} [sModelName] Optional model name\n * @returns {this} The control instance for chaining\n */\n public setBindingContext(oContext: sap.ui.model.Context | null | undefined, sModelName?: string): this {\n super.setBindingContext(oContext, sModelName);\n this.initODataDelegate();\n return this;\n }\n\n /**\n * Standard UI5 method override.\n * Binds the element to the given path and attaches a change listener to re-evaluate\n * the OData delegate when the element binding resolves.\n * \n * @param {string | Record<string, unknown>} vPath The binding path or configuration object\n * @param {object} [mParameters] Optional mapping parameters\n * @returns {this} Reference to this instance for chaining\n */\n public bindElement(vPath: string | Record<string, unknown>, mParameters?: object): this {\n super.bindElement(vPath, mParameters);\n const sModelName = typeof vPath === \"object\" ? vPath.model : undefined;\n const oBinding = this.getElementBinding(sModelName);\n if (oBinding) {\n oBinding.attachChange(() => {\n this.initODataDelegate();\n });\n }\n return this;\n }\n\n /**\n * Standard UI5 Lifecycle Hook.\n * Evaluates the initial properties and spawns the GeneratorHost.\n * It handles the complex lifecycle task of copying all bindings, raw properties, and event listeners \n * down to the inner host perfectly transparently.\n */\n public onBeforeRendering(): void {\n Logger.debug(\"[MetaUI DynamicHost]\", `onBeforeRendering called. _initializedInner: ${this._initializedInner}`, \"DynamicHost\");\n\n this.initODataDelegate();\n\n if (!this._initializedInner) {\n const schema = this.getProperty(\"schemaDefinition\");\n const dataJson = this.getProperty(\"dataJson\");\n const data = this.getProperty(\"data\");\n\n const hasSchema = !!schema;\n const hasData = !!dataJson || !!data;\n\n Logger.debug(\"[MetaUI DynamicHost]\", `Evaluating boot. hasSchema: ${hasSchema}, hasData: ${hasData}`, \"DynamicHost\");\n\n // Only boot if we have either a schema or some data to infer from\n if (hasSchema || hasData) {\n if (this.getProperty(\"debugMode\")) {\n Logger.debug(\"[MetaUI DynamicHost]\", `Booting inner host. hasSchema: ${hasSchema}, hasData: ${hasData}`, \"DynamicHost\");\n }\n // The architectural Facade router logic:\n // We've simplified this! We no longer use HostFactory or separate subclasses.\n // GeneratorHost is fully capable of inferring the schema if none is provided.\n this._innerHost = new GeneratorHost();\n\n // 1. Forward all static values to the spawned host BEFORE mounting.\n // Since we no longer use bindProperty, it's perfectly safe to set raw properties before mounting.\n const props = this.getMetadata().getProperties();\n for (const propName in props) {\n const val = super.getProperty(propName);\n if (val !== null && val !== undefined) {\n this._innerHost.setProperty(propName, val);\n }\n }\n\n // 2. Mount so it inherits models and triggers lifecycle.\n this.setAggregation(\"_content\", this._innerHost);\n\n // 3. Forward all event subscriptions.\n // By proxying the events upwards, the developer can subscribe to `<meta:DynamicHost submit=\"...\">` \n // and perfectly receive the inner host's submission event.\n const events = this.getMetadata().getEvents();\n for (const eventName in events) {\n this._innerHost.attachEvent(eventName, (oEvent: sap.ui.base.Event) => {\n // Natively push updated payload out to any bound Fiori Element properties.\n // Using super.setProperty prevents an infinite loop back down to _innerHost.\n if (eventName === \"submit\" || eventName === \"fieldChange\") {\n const params = oEvent.getParameters();\n if (params.payload) {\n super.setProperty(\"data\", params.payload, true);\n\n const str = params.payloadJson || JSON.stringify(params.payload, null, 2);\n super.setProperty(\"dataJson\", str, true);\n }\n if (eventName === \"fieldChange\" && this.odataDelegate) {\n this.odataDelegate.handleFieldChange(params.fieldPath, params.value);\n }\n }\n this.fireEvent(eventName, oEvent.getParameters());\n });\n }\n\n this._initializedInner = true;\n }\n }\n }\n\n /**\n * Overrides standard UI5 setProperty to act as a transparent proxy.\n * When a property is updated on the wrapper (either programmatically or via a binding update),\n * it instantly mirrors that value down to the inner instantiated host.\n */\n public setProperty(propertyName: string, value: unknown, suppressInvalidate?: boolean): this {\n if (propertyName === \"data\" || propertyName === \"dataJson\" || propertyName === \"schemaDefinition\") {\n if (this.getProperty(\"debugMode\")) {\n Logger.debug(\"[MetaUI DynamicHost]\", `Wrapper received setProperty: ${propertyName}`, \"DynamicHost\");\n }\n }\n super.setProperty(propertyName, value, suppressInvalidate);\n if (this._innerHost) {\n this._innerHost.setProperty(propertyName, value, suppressInvalidate);\n } else if (propertyName === \"data\" || propertyName === \"dataJson\" || propertyName === \"schemaDefinition\") {\n if (this.getProperty(\"debugMode\")) {\n Logger.debug(\"[MetaUI DynamicHost]\", `_innerHost not yet initialized when ${propertyName} was set. Booting will happen on next render.`, \"DynamicHost\");\n }\n }\n return this;\n }\n\n\n\n\n\n /**\n * Programmatic API support. Routes dialog commands down to the spawned inner host.\n * If the inner host has not booted yet, it forces initialization immediately.\n * \n * @param {string} [title=\"Form\"] The title of the dialog\n * @param {string} [submitButtonText=\"OK\"] The text for the primary action button\n * @param {string} [cancelButtonText=\"Cancel\"] The text for the cancel button\n */\n public openInDialog(title?: string, submitButtonText?: string, cancelButtonText?: string): void {\n if (!this._innerHost) {\n this.onBeforeRendering(); // Force init if they bypassed UI5 rendering\n }\n this._innerHost?.openInDialog(title, submitButtonText, cancelButtonText);\n }\n\n /**\n * Proxies submission triggering down to the instantiated generator host.\n * Evaluates the internal Engine validation suite and returns true if structurally sound.\n * \n * @returns {boolean} True if the internal payload passes schema validation, false otherwise.\n */\n public triggerSubmit(): boolean {\n if (!this._innerHost) {\n return false;\n }\n return this._innerHost.triggerSubmit();\n }\n\n /**\n * Overrides standard UI5 getProperty to transparently pull extracted data from the inner host.\n * Ensures that querying the DynamicHost facade for `data` always yields the freshest payload.\n * \n * @param {string} propertyName The name of the property to retrieve\n * @returns {unknown} The property value\n */\n public getProperty(propertyName: string): unknown {\n if (propertyName === \"outputData\") {\n propertyName = \"data\"; // Forward deprecated outputData to data\n }\n if (this._innerHost && (propertyName === \"data\" || propertyName === \"dataJson\")) {\n return this._innerHost.getProperty(propertyName);\n }\n return super.getProperty(propertyName);\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -99,6 +99,17 @@ export default class DynamicHost extends Control {
99
99
  */
100
100
  private initODataDelegate(): void {
101
101
  if (!this.odataDelegate) {
102
+ // Guard: If the user explicitly bound dataJson, do not steal the context.
103
+ if (this.getBindingInfo("dataJson")) {
104
+ return;
105
+ }
106
+
107
+ // Guard: If the user explicitly bound 'data' to a specific property path, do not steal the context.
108
+ const dataBinding = this.getBindingInfo("data") as any;
109
+ if (dataBinding && dataBinding.path && dataBinding.path !== "") {
110
+ return;
111
+ }
112
+
102
113
  const oContext = this.getBindingContext("odata") || this.getBindingContext();
103
114
  if (oContext) {
104
115
  Logger.debug("[MetaUI DynamicHost]", `Context found for delegate initialization: ${oContext.getPath()}`, "DynamicHost");
@@ -28,6 +28,8 @@ sap.ui.define(["./ConditionEngine", "./PluginRegistry", "sap/m/Text", "../utils/
28
28
 
29
29
  /** Deterministic scope ID injected by the host control to prevent clone collisions. */
30
30
 
31
+ /** Callback to notify the host that an internal field changed. */
32
+
31
33
  /** Tracks whether the entire engine is running in Editable mode. */
32
34
  isEditable = true;
33
35
 
@@ -1 +1 @@
1
- {"version":3,"file":"Engine-dbg.js","names":["ConditionEngine","___ConditionEngine","PluginRegistry","___PluginRegistry","Logger","___utils_Logger","DefaultLayoutGenerator","___DefaultLayoutGenerator","Engine","conditionEngine","activePlugins","isEditable","constructor","editable","build","schema","model","modelName","onSubmit","engineScopeId","onChange","activeModel","isValid","fieldKey","errorMessage","controlId","handleEvent","ensureLayout","warn","layoutStrategy","type","layoutManager","getInstance","getLayout","render","error","msg","message","showErrorPopup","Text","text","generateField","fieldMeta","bindingPath","isTemplate","plugin","getPlugin","ui","widget","setEditable","push","path","scopeId","undefined","control","registerPlugin","generateLayout","validateAll","errors","item","result","validate","replace","name","destroy","messageManager","Messaging","existingMessages","getMessageModel","getData","messagesToRemove","targetPath","matched","filter","getTarget","getMessageProcessor","getId","length","removeMessages","__exports","__esModule"],"sources":["Engine.ts"],"sourcesContent":["/**\n * @file Engine.ts\n * @description The central orchestrator that routes data between the Layout Factory and Plugin Registry (v2).\n */\n\nimport { ISchema, IPropertyMetadata } from \"../interfaces/ISchema\";\nimport { ILayoutManager } from \"../interfaces/ILayoutManager\";\nimport { IPlugin, IPluginValidationResult } from \"../interfaces/IPlugin\";\nimport { ConditionEngine } from \"./ConditionEngine\";\nimport { PluginRegistry } from \"./PluginRegistry\";\nimport Control from \"sap/ui/core/Control\";\nimport VBox from \"sap/m/VBox\";\nimport Text from \"sap/m/Text\";\nimport { Logger } from \"../utils/Logger\";\nimport { DefaultLayoutGenerator } from \"./DefaultLayoutGenerator\";\nimport Core from \"sap/ui/core/Core\";\nimport Messaging from \"sap/ui/core/Messaging\";\n\n/**\n * The Engine is responsible for translating a normalized schema into a physical UI5 layout.\n * It delegates layout generation to the configured `LayoutManager` and field generation to the `PluginRegistry`.\n * It strictly routes execution flow and tracks active plugins for validation.\n * It embodies the \"Plugin-First Philosophy\" by routing all complex field and layout rendering\n * through discrete, decoupled plugins rather than handling native overrides.\n * \n * @namespace nz.co.siliconst.ui5.metaui.core\n * @public\n */\nexport class Engine {\n /** Handles dynamic conditional logic across the active form. */\n private conditionEngine: ConditionEngine | null = null;\n\n /** Array of all instantiated plugins generated during the current build. */\n private activePlugins: { plugin: IPlugin, path: string }[] = [];\n\n /** Deterministic scope ID injected by the host control to prevent clone collisions. */\n public engineScopeId?: string;\n\n private activeModel?: sap.ui.model.Model;\n\n /** Tracks whether the entire engine is running in Editable mode. */\n public readonly isEditable: boolean = true;\n\n /**\n * Initializes a new Engine instance.\n * @param editable Whether the engine should render form fields as editable or read-only.\n */\n constructor(editable: boolean = true) {\n this.isEditable = editable;\n }\n\n /**\n * Bootstraps the layout generation process by resolving the correct layout strategy.\n * \n * @param schema The normalized JSON schema representing the view.\n * @param model The active StateManager JSONModel instance.\n * @param modelName The UI5 model alias used for isolation.\n * @param onSubmit Callback fired when form is submitted.\n * @param engineScopeId Deterministic scope ID for this engine instance.\n * @param onChange Callback fired when field values change.\n * @returns The generated root UI5 Control container.\n */\n public build(schema: ISchema, model: sap.ui.model.Model, modelName: string = \"meta\", onSubmit?: () => void, engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.conditionEngine = new ConditionEngine(schema);\n this.activePlugins = [];\n this.activeModel = model;\n this.engineScopeId = engineScopeId;\n this.onChange = (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => {\n if (this.conditionEngine && fieldKey) {\n this.conditionEngine.handleEvent(fieldKey, isValid);\n }\n if (onChange) {\n onChange(isValid, fieldKey, errorMessage, controlId);\n }\n };\n\n try {\n // Intercept and synthesize a default layout if the developer/backend failed to provide one\n if (DefaultLayoutGenerator.ensureLayout(schema)) {\n Logger.warn(\"[MetaUI Engine] Missing 'uiLayout' array in schema. Synthesized a default layout mapping to prevent a blank render.\");\n }\n\n const layoutStrategy = schema.layoutStrategy || (schema.type === \"array\" ? \"table\" : \"form\");\n const layoutManager = PluginRegistry.getInstance().getLayout(layoutStrategy);\n\n return layoutManager.render(schema, modelName, this, onSubmit);\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(\"[MetaUI Engine] Critical error during layout generation\", msg);\n Logger.showErrorPopup(`Engine failed to generate the layout.\\n\\nDetails: ${msg}`);\n return new Text({ text: \"Critical Layout Error\" });\n }\n }\n\n /**\n * Instantiates the correct plugin for a specific field based on type and widget hints,\n * and tracks the plugin for global validation.\n * \n * @param fieldMeta The metadata schema specific to the field.\n * @param bindingPath The JSON path representing the field within the payload.\n * @param modelName The UI5 JSONModel name used for data binding.\n * @returns The generated UI5 Control for the field.\n */\n public generateField(fieldMeta: IPropertyMetadata, bindingPath: string, modelName: string, isTemplate: boolean = false): Control {\n try {\n const plugin = PluginRegistry.getInstance().getPlugin(fieldMeta.type || \"string\", fieldMeta.ui?.widget);\n plugin.setEditable(this.isEditable);\n\n if (!isTemplate) {\n this.activePlugins.push({ plugin, path: bindingPath });\n }\n const scopeId = isTemplate ? undefined : this.engineScopeId;\n const control = plugin.render(fieldMeta, bindingPath, modelName, scopeId, this.onChange);\n\n if (this.conditionEngine) {\n this.conditionEngine.registerPlugin(bindingPath, plugin);\n }\n\n return control;\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI Engine] Failed to generate field at ${bindingPath}`, msg);\n Logger.showErrorPopup(`Failed to generate field '${bindingPath}'.\\n\\nDetails: ${msg}`);\n return new Text({ text: `[Error generating field ${bindingPath}]` });\n }\n }\n\n /**\n * Generates a sub-layout (like an embedded table or nested form) without \n * destroying the current Engine state or Condition tracking.\n * \n * @param schema The normalized JSON schema representing the view.\n * @param modelName The UI5 JSONModel name used for data binding (defaults to \"meta\").\n * @param bindingPath Optional path to bind the sub-layout to a specific array/object property.\n * @returns The generated root UI5 Control container.\n */\n public generateLayout(schema: ISchema, modelName: string, bindingPath?: string): Control {\n try {\n const layoutStrategy = schema.layoutStrategy || (schema.type === \"array\" ? \"table\" : \"form\");\n const layoutManager = PluginRegistry.getInstance().getLayout(layoutStrategy);\n return layoutManager.render(schema, modelName, this, undefined, bindingPath);\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI Engine] Critical error generating sub-layout for ${bindingPath}`, msg);\n Logger.showErrorPopup(`Engine failed to generate a sub-layout.\\n\\nDetails: ${msg}`);\n return new Text({ text: \"Critical Sub-Layout Error\" });\n }\n }\n\n /**\n * Iterates through all active plugins and triggers their internal validation pipelines.\n * \n * @returns {IPluginValidationResult[]} Array of validation error objects. Empty array if valid.\n */\n public validateAll(): IPluginValidationResult[] {\n const errors: IPluginValidationResult[] = [];\n for (const item of this.activePlugins) {\n try {\n const result = item.plugin.validate();\n if (!result.isValid) {\n // Ensure the path is bound to the error so GeneratorHost knows where to target it\n result.fieldKey = result.fieldKey || item.path.replace(/^\\//, \"\");\n errors.push(result);\n // Add console log to find which plugin fails silently\n Logger.error(\"[MetaUI Validation] Plugin failed validation silently:\", item.path || item.plugin.constructor.name);\n }\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI Validation] Exception during plugin validation at path ${item.path}`, msg);\n errors.push({ isValid: false, errorMessage: `Validation crashed: ${msg}`, fieldKey: item.path.replace(/^\\//, \"\") });\n }\n }\n return errors;\n }\n\n /**\n * Cleans up internal state and destroys the condition engine to prevent memory leaks.\n */\n public destroy(): void {\n if (this.conditionEngine) {\n this.conditionEngine.destroy();\n this.conditionEngine = null;\n }\n\n // ------------------------------------------------------------------------\n // Ghost Error Prevention\n // Flush MessageManager for active plugins before destroying their controls\n // ------------------------------------------------------------------------\n const messageManager = Messaging;\n const existingMessages = messageManager.getMessageModel().getData();\n const messagesToRemove: sap.ui.core.message.Message[] = [];\n\n for (const item of this.activePlugins) {\n if (this.activeModel) {\n const targetPath = `/${item.path.replace(/^\\//, \"\")}`;\n const matched = existingMessages.filter((msg: sap.ui.core.message.Message) =>\n msg.getTarget() === targetPath && msg.getMessageProcessor() && msg.getMessageProcessor().getId() === this.activeModel.getId()\n );\n messagesToRemove.push(...matched);\n }\n if (typeof item.plugin.destroy === \"function\") {\n item.plugin.destroy();\n }\n }\n\n if (messagesToRemove.length > 0) {\n messageManager.removeMessages(messagesToRemove);\n }\n\n this.activePlugins = [];\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"Engine-dbg.js","names":["ConditionEngine","___ConditionEngine","PluginRegistry","___PluginRegistry","Logger","___utils_Logger","DefaultLayoutGenerator","___DefaultLayoutGenerator","Engine","conditionEngine","activePlugins","isEditable","constructor","editable","build","schema","model","modelName","onSubmit","engineScopeId","onChange","activeModel","isValid","fieldKey","errorMessage","controlId","handleEvent","ensureLayout","warn","layoutStrategy","type","layoutManager","getInstance","getLayout","render","error","msg","message","showErrorPopup","Text","text","generateField","fieldMeta","bindingPath","isTemplate","plugin","getPlugin","ui","widget","setEditable","push","path","scopeId","undefined","control","registerPlugin","generateLayout","validateAll","errors","item","result","validate","replace","name","destroy","messageManager","Messaging","existingMessages","getMessageModel","getData","messagesToRemove","targetPath","matched","filter","getTarget","getMessageProcessor","getId","length","removeMessages","__exports","__esModule"],"sources":["Engine.ts"],"sourcesContent":["/**\n * @file Engine.ts\n * @description The central orchestrator that routes data between the Layout Factory and Plugin Registry (v2).\n */\n\nimport { ISchema, IPropertyMetadata } from \"../interfaces/ISchema\";\nimport { ILayoutManager } from \"../interfaces/ILayoutManager\";\nimport { IPlugin, IPluginValidationResult } from \"../interfaces/IPlugin\";\nimport { ConditionEngine } from \"./ConditionEngine\";\nimport { PluginRegistry } from \"./PluginRegistry\";\nimport Control from \"sap/ui/core/Control\";\nimport VBox from \"sap/m/VBox\";\nimport Text from \"sap/m/Text\";\nimport { Logger } from \"../utils/Logger\";\nimport { DefaultLayoutGenerator } from \"./DefaultLayoutGenerator\";\nimport Core from \"sap/ui/core/Core\";\nimport Messaging from \"sap/ui/core/Messaging\";\n\n/**\n * The Engine is responsible for translating a normalized schema into a physical UI5 layout.\n * It delegates layout generation to the configured `LayoutManager` and field generation to the `PluginRegistry`.\n * It strictly routes execution flow and tracks active plugins for validation.\n * It embodies the \"Plugin-First Philosophy\" by routing all complex field and layout rendering\n * through discrete, decoupled plugins rather than handling native overrides.\n * \n * @namespace nz.co.siliconst.ui5.metaui.core\n * @public\n */\nexport class Engine {\n /** Handles dynamic conditional logic across the active form. */\n private conditionEngine: ConditionEngine | null = null;\n\n /** Array of all instantiated plugins generated during the current build. */\n private activePlugins: { plugin: IPlugin, path: string }[] = [];\n\n /** Deterministic scope ID injected by the host control to prevent clone collisions. */\n public engineScopeId?: string;\n\n private activeModel?: sap.ui.model.Model;\n\n /** Callback to notify the host that an internal field changed. */\n public onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void;\n\n /** Tracks whether the entire engine is running in Editable mode. */\n public readonly isEditable: boolean = true;\n\n /**\n * Initializes a new Engine instance.\n * @param editable Whether the engine should render form fields as editable or read-only.\n */\n constructor(editable: boolean = true) {\n this.isEditable = editable;\n }\n\n /**\n * Bootstraps the layout generation process by resolving the correct layout strategy.\n * \n * @param schema The normalized JSON schema representing the view.\n * @param model The active StateManager JSONModel instance.\n * @param modelName The UI5 model alias used for isolation.\n * @param onSubmit Callback fired when form is submitted.\n * @param engineScopeId Deterministic scope ID for this engine instance.\n * @param onChange Callback fired when field values change.\n * @returns The generated root UI5 Control container.\n */\n public build(schema: ISchema, model: sap.ui.model.Model, modelName: string = \"meta\", onSubmit?: () => void, engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.conditionEngine = new ConditionEngine(schema);\n this.activePlugins = [];\n this.activeModel = model;\n this.engineScopeId = engineScopeId;\n this.onChange = (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => {\n if (this.conditionEngine && fieldKey) {\n this.conditionEngine.handleEvent(fieldKey, isValid);\n }\n if (onChange) {\n onChange(isValid, fieldKey, errorMessage, controlId);\n }\n };\n\n try {\n // Intercept and synthesize a default layout if the developer/backend failed to provide one\n if (DefaultLayoutGenerator.ensureLayout(schema)) {\n Logger.warn(\"[MetaUI Engine] Missing 'uiLayout' array in schema. Synthesized a default layout mapping to prevent a blank render.\");\n }\n\n const layoutStrategy = schema.layoutStrategy || (schema.type === \"array\" ? \"table\" : \"form\");\n const layoutManager = PluginRegistry.getInstance().getLayout(layoutStrategy);\n\n return layoutManager.render(schema, modelName, this, onSubmit);\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(\"[MetaUI Engine] Critical error during layout generation\", msg);\n Logger.showErrorPopup(`Engine failed to generate the layout.\\n\\nDetails: ${msg}`);\n return new Text({ text: \"Critical Layout Error\" });\n }\n }\n\n /**\n * Instantiates the correct plugin for a specific field based on type and widget hints,\n * and tracks the plugin for global validation.\n * \n * @param fieldMeta The metadata schema specific to the field.\n * @param bindingPath The JSON path representing the field within the payload.\n * @param modelName The UI5 JSONModel name used for data binding.\n * @returns The generated UI5 Control for the field.\n */\n public generateField(fieldMeta: IPropertyMetadata, bindingPath: string, modelName: string, isTemplate: boolean = false): Control {\n try {\n const plugin = PluginRegistry.getInstance().getPlugin(fieldMeta.type || \"string\", fieldMeta.ui?.widget);\n plugin.setEditable(this.isEditable);\n\n if (!isTemplate) {\n this.activePlugins.push({ plugin, path: bindingPath });\n }\n const scopeId = isTemplate ? undefined : this.engineScopeId;\n const control = plugin.render(fieldMeta, bindingPath, modelName, scopeId, this.onChange);\n\n if (this.conditionEngine) {\n this.conditionEngine.registerPlugin(bindingPath, plugin);\n }\n\n return control;\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI Engine] Failed to generate field at ${bindingPath}`, msg);\n Logger.showErrorPopup(`Failed to generate field '${bindingPath}'.\\n\\nDetails: ${msg}`);\n return new Text({ text: `[Error generating field ${bindingPath}]` });\n }\n }\n\n /**\n * Generates a sub-layout (like an embedded table or nested form) without \n * destroying the current Engine state or Condition tracking.\n * \n * @param schema The normalized JSON schema representing the view.\n * @param modelName The UI5 JSONModel name used for data binding (defaults to \"meta\").\n * @param bindingPath Optional path to bind the sub-layout to a specific array/object property.\n * @returns The generated root UI5 Control container.\n */\n public generateLayout(schema: ISchema, modelName: string, bindingPath?: string): Control {\n try {\n const layoutStrategy = schema.layoutStrategy || (schema.type === \"array\" ? \"table\" : \"form\");\n const layoutManager = PluginRegistry.getInstance().getLayout(layoutStrategy);\n return layoutManager.render(schema, modelName, this, undefined, bindingPath);\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI Engine] Critical error generating sub-layout for ${bindingPath}`, msg);\n Logger.showErrorPopup(`Engine failed to generate a sub-layout.\\n\\nDetails: ${msg}`);\n return new Text({ text: \"Critical Sub-Layout Error\" });\n }\n }\n\n /**\n * Iterates through all active plugins and triggers their internal validation pipelines.\n * \n * @returns {IPluginValidationResult[]} Array of validation error objects. Empty array if valid.\n */\n public validateAll(): IPluginValidationResult[] {\n const errors: IPluginValidationResult[] = [];\n for (const item of this.activePlugins) {\n try {\n const result = item.plugin.validate();\n if (!result.isValid) {\n // Ensure the path is bound to the error so GeneratorHost knows where to target it\n result.fieldKey = result.fieldKey || item.path.replace(/^\\//, \"\");\n errors.push(result);\n // Add console log to find which plugin fails silently\n Logger.error(\"[MetaUI Validation] Plugin failed validation silently:\", item.path || item.plugin.constructor.name);\n }\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI Validation] Exception during plugin validation at path ${item.path}`, msg);\n errors.push({ isValid: false, errorMessage: `Validation crashed: ${msg}`, fieldKey: item.path.replace(/^\\//, \"\") });\n }\n }\n return errors;\n }\n\n /**\n * Cleans up internal state and destroys the condition engine to prevent memory leaks.\n */\n public destroy(): void {\n if (this.conditionEngine) {\n this.conditionEngine.destroy();\n this.conditionEngine = null;\n }\n\n // ------------------------------------------------------------------------\n // Ghost Error Prevention\n // Flush MessageManager for active plugins before destroying their controls\n // ------------------------------------------------------------------------\n const messageManager = Messaging;\n const existingMessages = messageManager.getMessageModel().getData();\n const messagesToRemove: sap.ui.core.message.Message[] = [];\n\n for (const item of this.activePlugins) {\n if (this.activeModel) {\n const targetPath = `/${item.path.replace(/^\\//, \"\")}`;\n const matched = existingMessages.filter((msg: sap.ui.core.message.Message) =>\n msg.getTarget() === targetPath && msg.getMessageProcessor() && msg.getMessageProcessor().getId() === this.activeModel.getId()\n );\n messagesToRemove.push(...matched);\n }\n if (typeof item.plugin.destroy === \"function\") {\n item.plugin.destroy();\n }\n }\n\n if (messagesToRemove.length > 0) {\n messageManager.removeMessages(messagesToRemove);\n }\n\n this.activePlugins = [];\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -24,6 +24,8 @@ declare module "nz/co/siliconst/ui5/metaui/core/Engine" {
24
24
  /** Deterministic scope ID injected by the host control to prevent clone collisions. */
25
25
  engineScopeId?: string;
26
26
  private activeModel?;
27
+ /** Callback to notify the host that an internal field changed. */
28
+ onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void;
27
29
  /** Tracks whether the entire engine is running in Editable mode. */
28
30
  readonly isEditable: boolean;
29
31
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"Engine.d.ts","sourceRoot":"../../../../../../../..","sources":["src/nz/co/siliconst/ui5/metaui/core/Engine.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,wCAAwC,CAAC;IACxD;;;OAGG;IAEH,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,+CAA+C,CAAC;IAE3F,OAAO,EAAW,uBAAuB,EAAE,MAAM,+CAA+C,CAAC;IAGjG,OAAO,OAAO,MAAM,qBAAqB,CAAC;IAQ1C;;;;;;;;;OASG;IACH,MAAa,MAAM;QACf,gEAAgE;QAChE,OAAO,CAAC,eAAe,CAAgC;QAEvD,4EAA4E;QAC5E,OAAO,CAAC,aAAa,CAA2C;QAEhE,uFAAuF;QAChF,aAAa,CAAC,EAAE,MAAM,CAAC;QAE9B,OAAO,CAAC,WAAW,CAAC,CAAqB;QAEzC,oEAAoE;QACpE,SAAgB,UAAU,EAAE,OAAO,CAAQ;QAE3C;;;WAGG;oBACS,QAAQ,GAAE,OAAc;QAIpC;;;;;;;;;;WAUG;QACI,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,SAAS,GAAE,MAAe,EAAE,QAAQ,CAAC,EAAE,MAAM,IAAI,EAAE,aAAa,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO;QAgCjP;;;;;;;;WAQG;QACI,aAAa,CAAC,SAAS,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,GAAE,OAAe,GAAG,OAAO;QAwBhI;;;;;;;;WAQG;QACI,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO;QAaxF;;;;WAIG;QACI,WAAW,IAAI,uBAAuB,EAAE;QAqB/C;;WAEG;QACI,OAAO,IAAI,IAAI;KAiCzB;CAEA"}
1
+ {"version":3,"file":"Engine.d.ts","sourceRoot":"../../../../../../../..","sources":["src/nz/co/siliconst/ui5/metaui/core/Engine.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,wCAAwC,CAAC;IACxD;;;OAGG;IAEH,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,+CAA+C,CAAC;IAE3F,OAAO,EAAW,uBAAuB,EAAE,MAAM,+CAA+C,CAAC;IAGjG,OAAO,OAAO,MAAM,qBAAqB,CAAC;IAQ1C;;;;;;;;;OASG;IACH,MAAa,MAAM;QACf,gEAAgE;QAChE,OAAO,CAAC,eAAe,CAAgC;QAEvD,4EAA4E;QAC5E,OAAO,CAAC,aAAa,CAA2C;QAEhE,uFAAuF;QAChF,aAAa,CAAC,EAAE,MAAM,CAAC;QAE9B,OAAO,CAAC,WAAW,CAAC,CAAqB;QAEzC,kEAAkE;QAC3D,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;QAE3G,oEAAoE;QACpE,SAAgB,UAAU,EAAE,OAAO,CAAQ;QAE3C;;;WAGG;oBACS,QAAQ,GAAE,OAAc;QAIpC;;;;;;;;;;WAUG;QACI,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,SAAS,GAAE,MAAe,EAAE,QAAQ,CAAC,EAAE,MAAM,IAAI,EAAE,aAAa,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO;QAgCjP;;;;;;;;WAQG;QACI,aAAa,CAAC,SAAS,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,GAAE,OAAe,GAAG,OAAO;QAwBhI;;;;;;;;WAQG;QACI,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO;QAaxF;;;;WAIG;QACI,WAAW,IAAI,uBAAuB,EAAE;QAqB/C;;WAEG;QACI,OAAO,IAAI,IAAI;KAiCzB;CAEA"}
@@ -1 +1 @@
1
- {"version":3,"file":"Engine.js","names":["ConditionEngine","___ConditionEngine","PluginRegistry","___PluginRegistry","Logger","___utils_Logger","DefaultLayoutGenerator","___DefaultLayoutGenerator","Engine","conditionEngine","activePlugins","isEditable","constructor","editable","this","build","schema","model","modelName","onSubmit","engineScopeId","onChange","activeModel","isValid","fieldKey","errorMessage","controlId","handleEvent","ensureLayout","warn","layoutStrategy","type","layoutManager","getInstance","getLayout","render","error","msg","message","showErrorPopup","Text","text","generateField","fieldMeta","bindingPath","isTemplate","plugin","getPlugin","ui","widget","setEditable","push","path","scopeId","undefined","control","registerPlugin","generateLayout","validateAll","errors","item","result","validate","replace","name","destroy","messageManager","Messaging","existingMessages","getMessageModel","getData","messagesToRemove","targetPath","matched","filter","getTarget","getMessageProcessor","getId","length","removeMessages","__exports","__esModule"],"sources":["Engine.ts"],"sourcesContent":["/**\n * @file Engine.ts\n * @description The central orchestrator that routes data between the Layout Factory and Plugin Registry (v2).\n */\n\nimport { ISchema, IPropertyMetadata } from \"../interfaces/ISchema\";\nimport { ILayoutManager } from \"../interfaces/ILayoutManager\";\nimport { IPlugin, IPluginValidationResult } from \"../interfaces/IPlugin\";\nimport { ConditionEngine } from \"./ConditionEngine\";\nimport { PluginRegistry } from \"./PluginRegistry\";\nimport Control from \"sap/ui/core/Control\";\nimport VBox from \"sap/m/VBox\";\nimport Text from \"sap/m/Text\";\nimport { Logger } from \"../utils/Logger\";\nimport { DefaultLayoutGenerator } from \"./DefaultLayoutGenerator\";\nimport Core from \"sap/ui/core/Core\";\nimport Messaging from \"sap/ui/core/Messaging\";\n\n/**\n * The Engine is responsible for translating a normalized schema into a physical UI5 layout.\n * It delegates layout generation to the configured `LayoutManager` and field generation to the `PluginRegistry`.\n * It strictly routes execution flow and tracks active plugins for validation.\n * It embodies the \"Plugin-First Philosophy\" by routing all complex field and layout rendering\n * through discrete, decoupled plugins rather than handling native overrides.\n * \n * @namespace nz.co.siliconst.ui5.metaui.core\n * @public\n */\nexport class Engine {\n /** Handles dynamic conditional logic across the active form. */\n private conditionEngine: ConditionEngine | null = null;\n\n /** Array of all instantiated plugins generated during the current build. */\n private activePlugins: { plugin: IPlugin, path: string }[] = [];\n\n /** Deterministic scope ID injected by the host control to prevent clone collisions. */\n public engineScopeId?: string;\n\n private activeModel?: sap.ui.model.Model;\n\n /** Tracks whether the entire engine is running in Editable mode. */\n public readonly isEditable: boolean = true;\n\n /**\n * Initializes a new Engine instance.\n * @param editable Whether the engine should render form fields as editable or read-only.\n */\n constructor(editable: boolean = true) {\n this.isEditable = editable;\n }\n\n /**\n * Bootstraps the layout generation process by resolving the correct layout strategy.\n * \n * @param schema The normalized JSON schema representing the view.\n * @param model The active StateManager JSONModel instance.\n * @param modelName The UI5 model alias used for isolation.\n * @param onSubmit Callback fired when form is submitted.\n * @param engineScopeId Deterministic scope ID for this engine instance.\n * @param onChange Callback fired when field values change.\n * @returns The generated root UI5 Control container.\n */\n public build(schema: ISchema, model: sap.ui.model.Model, modelName: string = \"meta\", onSubmit?: () => void, engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.conditionEngine = new ConditionEngine(schema);\n this.activePlugins = [];\n this.activeModel = model;\n this.engineScopeId = engineScopeId;\n this.onChange = (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => {\n if (this.conditionEngine && fieldKey) {\n this.conditionEngine.handleEvent(fieldKey, isValid);\n }\n if (onChange) {\n onChange(isValid, fieldKey, errorMessage, controlId);\n }\n };\n\n try {\n // Intercept and synthesize a default layout if the developer/backend failed to provide one\n if (DefaultLayoutGenerator.ensureLayout(schema)) {\n Logger.warn(\"[MetaUI Engine] Missing 'uiLayout' array in schema. Synthesized a default layout mapping to prevent a blank render.\");\n }\n\n const layoutStrategy = schema.layoutStrategy || (schema.type === \"array\" ? \"table\" : \"form\");\n const layoutManager = PluginRegistry.getInstance().getLayout(layoutStrategy);\n\n return layoutManager.render(schema, modelName, this, onSubmit);\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(\"[MetaUI Engine] Critical error during layout generation\", msg);\n Logger.showErrorPopup(`Engine failed to generate the layout.\\n\\nDetails: ${msg}`);\n return new Text({ text: \"Critical Layout Error\" });\n }\n }\n\n /**\n * Instantiates the correct plugin for a specific field based on type and widget hints,\n * and tracks the plugin for global validation.\n * \n * @param fieldMeta The metadata schema specific to the field.\n * @param bindingPath The JSON path representing the field within the payload.\n * @param modelName The UI5 JSONModel name used for data binding.\n * @returns The generated UI5 Control for the field.\n */\n public generateField(fieldMeta: IPropertyMetadata, bindingPath: string, modelName: string, isTemplate: boolean = false): Control {\n try {\n const plugin = PluginRegistry.getInstance().getPlugin(fieldMeta.type || \"string\", fieldMeta.ui?.widget);\n plugin.setEditable(this.isEditable);\n\n if (!isTemplate) {\n this.activePlugins.push({ plugin, path: bindingPath });\n }\n const scopeId = isTemplate ? undefined : this.engineScopeId;\n const control = plugin.render(fieldMeta, bindingPath, modelName, scopeId, this.onChange);\n\n if (this.conditionEngine) {\n this.conditionEngine.registerPlugin(bindingPath, plugin);\n }\n\n return control;\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI Engine] Failed to generate field at ${bindingPath}`, msg);\n Logger.showErrorPopup(`Failed to generate field '${bindingPath}'.\\n\\nDetails: ${msg}`);\n return new Text({ text: `[Error generating field ${bindingPath}]` });\n }\n }\n\n /**\n * Generates a sub-layout (like an embedded table or nested form) without \n * destroying the current Engine state or Condition tracking.\n * \n * @param schema The normalized JSON schema representing the view.\n * @param modelName The UI5 JSONModel name used for data binding (defaults to \"meta\").\n * @param bindingPath Optional path to bind the sub-layout to a specific array/object property.\n * @returns The generated root UI5 Control container.\n */\n public generateLayout(schema: ISchema, modelName: string, bindingPath?: string): Control {\n try {\n const layoutStrategy = schema.layoutStrategy || (schema.type === \"array\" ? \"table\" : \"form\");\n const layoutManager = PluginRegistry.getInstance().getLayout(layoutStrategy);\n return layoutManager.render(schema, modelName, this, undefined, bindingPath);\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI Engine] Critical error generating sub-layout for ${bindingPath}`, msg);\n Logger.showErrorPopup(`Engine failed to generate a sub-layout.\\n\\nDetails: ${msg}`);\n return new Text({ text: \"Critical Sub-Layout Error\" });\n }\n }\n\n /**\n * Iterates through all active plugins and triggers their internal validation pipelines.\n * \n * @returns {IPluginValidationResult[]} Array of validation error objects. Empty array if valid.\n */\n public validateAll(): IPluginValidationResult[] {\n const errors: IPluginValidationResult[] = [];\n for (const item of this.activePlugins) {\n try {\n const result = item.plugin.validate();\n if (!result.isValid) {\n // Ensure the path is bound to the error so GeneratorHost knows where to target it\n result.fieldKey = result.fieldKey || item.path.replace(/^\\//, \"\");\n errors.push(result);\n // Add console log to find which plugin fails silently\n Logger.error(\"[MetaUI Validation] Plugin failed validation silently:\", item.path || item.plugin.constructor.name);\n }\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI Validation] Exception during plugin validation at path ${item.path}`, msg);\n errors.push({ isValid: false, errorMessage: `Validation crashed: ${msg}`, fieldKey: item.path.replace(/^\\//, \"\") });\n }\n }\n return errors;\n }\n\n /**\n * Cleans up internal state and destroys the condition engine to prevent memory leaks.\n */\n public destroy(): void {\n if (this.conditionEngine) {\n this.conditionEngine.destroy();\n this.conditionEngine = null;\n }\n\n // ------------------------------------------------------------------------\n // Ghost Error Prevention\n // Flush MessageManager for active plugins before destroying their controls\n // ------------------------------------------------------------------------\n const messageManager = Messaging;\n const existingMessages = messageManager.getMessageModel().getData();\n const messagesToRemove: sap.ui.core.message.Message[] = [];\n\n for (const item of this.activePlugins) {\n if (this.activeModel) {\n const targetPath = `/${item.path.replace(/^\\//, \"\")}`;\n const matched = existingMessages.filter((msg: sap.ui.core.message.Message) =>\n msg.getTarget() === targetPath && msg.getMessageProcessor() && msg.getMessageProcessor().getId() === this.activeModel.getId()\n );\n messagesToRemove.push(...matched);\n }\n if (typeof item.plugin.destroy === \"function\") {\n item.plugin.destroy();\n }\n }\n\n if (messagesToRemove.length > 0) {\n messageManager.removeMessages(messagesToRemove);\n }\n\n this.activePlugins = [];\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"Engine.js","names":["ConditionEngine","___ConditionEngine","PluginRegistry","___PluginRegistry","Logger","___utils_Logger","DefaultLayoutGenerator","___DefaultLayoutGenerator","Engine","conditionEngine","activePlugins","isEditable","constructor","editable","this","build","schema","model","modelName","onSubmit","engineScopeId","onChange","activeModel","isValid","fieldKey","errorMessage","controlId","handleEvent","ensureLayout","warn","layoutStrategy","type","layoutManager","getInstance","getLayout","render","error","msg","message","showErrorPopup","Text","text","generateField","fieldMeta","bindingPath","isTemplate","plugin","getPlugin","ui","widget","setEditable","push","path","scopeId","undefined","control","registerPlugin","generateLayout","validateAll","errors","item","result","validate","replace","name","destroy","messageManager","Messaging","existingMessages","getMessageModel","getData","messagesToRemove","targetPath","matched","filter","getTarget","getMessageProcessor","getId","length","removeMessages","__exports","__esModule"],"sources":["Engine.ts"],"sourcesContent":["/**\n * @file Engine.ts\n * @description The central orchestrator that routes data between the Layout Factory and Plugin Registry (v2).\n */\n\nimport { ISchema, IPropertyMetadata } from \"../interfaces/ISchema\";\nimport { ILayoutManager } from \"../interfaces/ILayoutManager\";\nimport { IPlugin, IPluginValidationResult } from \"../interfaces/IPlugin\";\nimport { ConditionEngine } from \"./ConditionEngine\";\nimport { PluginRegistry } from \"./PluginRegistry\";\nimport Control from \"sap/ui/core/Control\";\nimport VBox from \"sap/m/VBox\";\nimport Text from \"sap/m/Text\";\nimport { Logger } from \"../utils/Logger\";\nimport { DefaultLayoutGenerator } from \"./DefaultLayoutGenerator\";\nimport Core from \"sap/ui/core/Core\";\nimport Messaging from \"sap/ui/core/Messaging\";\n\n/**\n * The Engine is responsible for translating a normalized schema into a physical UI5 layout.\n * It delegates layout generation to the configured `LayoutManager` and field generation to the `PluginRegistry`.\n * It strictly routes execution flow and tracks active plugins for validation.\n * It embodies the \"Plugin-First Philosophy\" by routing all complex field and layout rendering\n * through discrete, decoupled plugins rather than handling native overrides.\n * \n * @namespace nz.co.siliconst.ui5.metaui.core\n * @public\n */\nexport class Engine {\n /** Handles dynamic conditional logic across the active form. */\n private conditionEngine: ConditionEngine | null = null;\n\n /** Array of all instantiated plugins generated during the current build. */\n private activePlugins: { plugin: IPlugin, path: string }[] = [];\n\n /** Deterministic scope ID injected by the host control to prevent clone collisions. */\n public engineScopeId?: string;\n\n private activeModel?: sap.ui.model.Model;\n\n /** Callback to notify the host that an internal field changed. */\n public onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void;\n\n /** Tracks whether the entire engine is running in Editable mode. */\n public readonly isEditable: boolean = true;\n\n /**\n * Initializes a new Engine instance.\n * @param editable Whether the engine should render form fields as editable or read-only.\n */\n constructor(editable: boolean = true) {\n this.isEditable = editable;\n }\n\n /**\n * Bootstraps the layout generation process by resolving the correct layout strategy.\n * \n * @param schema The normalized JSON schema representing the view.\n * @param model The active StateManager JSONModel instance.\n * @param modelName The UI5 model alias used for isolation.\n * @param onSubmit Callback fired when form is submitted.\n * @param engineScopeId Deterministic scope ID for this engine instance.\n * @param onChange Callback fired when field values change.\n * @returns The generated root UI5 Control container.\n */\n public build(schema: ISchema, model: sap.ui.model.Model, modelName: string = \"meta\", onSubmit?: () => void, engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.conditionEngine = new ConditionEngine(schema);\n this.activePlugins = [];\n this.activeModel = model;\n this.engineScopeId = engineScopeId;\n this.onChange = (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => {\n if (this.conditionEngine && fieldKey) {\n this.conditionEngine.handleEvent(fieldKey, isValid);\n }\n if (onChange) {\n onChange(isValid, fieldKey, errorMessage, controlId);\n }\n };\n\n try {\n // Intercept and synthesize a default layout if the developer/backend failed to provide one\n if (DefaultLayoutGenerator.ensureLayout(schema)) {\n Logger.warn(\"[MetaUI Engine] Missing 'uiLayout' array in schema. Synthesized a default layout mapping to prevent a blank render.\");\n }\n\n const layoutStrategy = schema.layoutStrategy || (schema.type === \"array\" ? \"table\" : \"form\");\n const layoutManager = PluginRegistry.getInstance().getLayout(layoutStrategy);\n\n return layoutManager.render(schema, modelName, this, onSubmit);\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(\"[MetaUI Engine] Critical error during layout generation\", msg);\n Logger.showErrorPopup(`Engine failed to generate the layout.\\n\\nDetails: ${msg}`);\n return new Text({ text: \"Critical Layout Error\" });\n }\n }\n\n /**\n * Instantiates the correct plugin for a specific field based on type and widget hints,\n * and tracks the plugin for global validation.\n * \n * @param fieldMeta The metadata schema specific to the field.\n * @param bindingPath The JSON path representing the field within the payload.\n * @param modelName The UI5 JSONModel name used for data binding.\n * @returns The generated UI5 Control for the field.\n */\n public generateField(fieldMeta: IPropertyMetadata, bindingPath: string, modelName: string, isTemplate: boolean = false): Control {\n try {\n const plugin = PluginRegistry.getInstance().getPlugin(fieldMeta.type || \"string\", fieldMeta.ui?.widget);\n plugin.setEditable(this.isEditable);\n\n if (!isTemplate) {\n this.activePlugins.push({ plugin, path: bindingPath });\n }\n const scopeId = isTemplate ? undefined : this.engineScopeId;\n const control = plugin.render(fieldMeta, bindingPath, modelName, scopeId, this.onChange);\n\n if (this.conditionEngine) {\n this.conditionEngine.registerPlugin(bindingPath, plugin);\n }\n\n return control;\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI Engine] Failed to generate field at ${bindingPath}`, msg);\n Logger.showErrorPopup(`Failed to generate field '${bindingPath}'.\\n\\nDetails: ${msg}`);\n return new Text({ text: `[Error generating field ${bindingPath}]` });\n }\n }\n\n /**\n * Generates a sub-layout (like an embedded table or nested form) without \n * destroying the current Engine state or Condition tracking.\n * \n * @param schema The normalized JSON schema representing the view.\n * @param modelName The UI5 JSONModel name used for data binding (defaults to \"meta\").\n * @param bindingPath Optional path to bind the sub-layout to a specific array/object property.\n * @returns The generated root UI5 Control container.\n */\n public generateLayout(schema: ISchema, modelName: string, bindingPath?: string): Control {\n try {\n const layoutStrategy = schema.layoutStrategy || (schema.type === \"array\" ? \"table\" : \"form\");\n const layoutManager = PluginRegistry.getInstance().getLayout(layoutStrategy);\n return layoutManager.render(schema, modelName, this, undefined, bindingPath);\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI Engine] Critical error generating sub-layout for ${bindingPath}`, msg);\n Logger.showErrorPopup(`Engine failed to generate a sub-layout.\\n\\nDetails: ${msg}`);\n return new Text({ text: \"Critical Sub-Layout Error\" });\n }\n }\n\n /**\n * Iterates through all active plugins and triggers their internal validation pipelines.\n * \n * @returns {IPluginValidationResult[]} Array of validation error objects. Empty array if valid.\n */\n public validateAll(): IPluginValidationResult[] {\n const errors: IPluginValidationResult[] = [];\n for (const item of this.activePlugins) {\n try {\n const result = item.plugin.validate();\n if (!result.isValid) {\n // Ensure the path is bound to the error so GeneratorHost knows where to target it\n result.fieldKey = result.fieldKey || item.path.replace(/^\\//, \"\");\n errors.push(result);\n // Add console log to find which plugin fails silently\n Logger.error(\"[MetaUI Validation] Plugin failed validation silently:\", item.path || item.plugin.constructor.name);\n }\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI Validation] Exception during plugin validation at path ${item.path}`, msg);\n errors.push({ isValid: false, errorMessage: `Validation crashed: ${msg}`, fieldKey: item.path.replace(/^\\//, \"\") });\n }\n }\n return errors;\n }\n\n /**\n * Cleans up internal state and destroys the condition engine to prevent memory leaks.\n */\n public destroy(): void {\n if (this.conditionEngine) {\n this.conditionEngine.destroy();\n this.conditionEngine = null;\n }\n\n // ------------------------------------------------------------------------\n // Ghost Error Prevention\n // Flush MessageManager for active plugins before destroying their controls\n // ------------------------------------------------------------------------\n const messageManager = Messaging;\n const existingMessages = messageManager.getMessageModel().getData();\n const messagesToRemove: sap.ui.core.message.Message[] = [];\n\n for (const item of this.activePlugins) {\n if (this.activeModel) {\n const targetPath = `/${item.path.replace(/^\\//, \"\")}`;\n const matched = existingMessages.filter((msg: sap.ui.core.message.Message) =>\n msg.getTarget() === targetPath && msg.getMessageProcessor() && msg.getMessageProcessor().getId() === this.activeModel.getId()\n );\n messagesToRemove.push(...matched);\n }\n if (typeof item.plugin.destroy === \"function\") {\n item.plugin.destroy();\n }\n }\n\n if (messagesToRemove.length > 0) {\n messageManager.removeMessages(messagesToRemove);\n }\n\n this.activePlugins = [];\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -38,6 +38,9 @@ export class Engine {
38
38
 
39
39
  private activeModel?: sap.ui.model.Model;
40
40
 
41
+ /** Callback to notify the host that an internal field changed. */
42
+ public onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void;
43
+
41
44
  /** Tracks whether the entire engine is running in Editable mode. */
42
45
  public readonly isEditable: boolean = true;
43
46
 
@@ -47,6 +47,11 @@ sap.ui.define(["sap/m/Table", "sap/m/Column", "sap/m/Text", "sap/m/ColumnListIte
47
47
  const data = Array.isArray(rawData) ? rawData : [];
48
48
  const newData = [...data, {}];
49
49
  model.setProperty(info.path, newData);
50
+
51
+ // CRITICAL: Notify the engine so it extracts payload and triggers liveUpdate
52
+ if (engine.onChange) {
53
+ engine.onChange(true, actualPath.replace(/^\//, ""));
54
+ }
50
55
  }
51
56
  })])]
52
57
  }),
@@ -65,6 +70,11 @@ sap.ui.define(["sap/m/Table", "sap/m/Column", "sap/m/Text", "sap/m/ColumnListIte
65
70
  const newData = [...data];
66
71
  newData.splice(index, 1);
67
72
  model.setProperty(arrayPath, newData);
73
+
74
+ // CRITICAL: Notify the engine so it extracts payload and triggers liveUpdate
75
+ if (engine.onChange) {
76
+ engine.onChange(true, actualPath.replace(/^\//, ""));
77
+ }
68
78
  }
69
79
  });
70
80
  const templateCells = [];