@siliconst/metaui 1.4.4 → 1.4.5
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.
- package/package.json +1 -1
- package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost-dbg.js +40 -1
- package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost-dbg.js.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost.d.ts +6 -0
- package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost.d.ts.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost.js +1 -1
- package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost.js.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost.ts +44 -0
- package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ODataDelegate-dbg.js +122 -0
- package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ODataDelegate-dbg.js.map +1 -0
- package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ODataDelegate.d.ts +49 -0
- package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ODataDelegate.d.ts.map +1 -0
- package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ODataDelegate.js +2 -0
- package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ODataDelegate.js.map +1 -0
- package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ODataDelegate.ts +118 -0
- package/src/nz/co/siliconst/ui5/metaui/core/DefaultLayoutGenerator-dbg.js +24 -8
- package/src/nz/co/siliconst/ui5/metaui/core/DefaultLayoutGenerator-dbg.js.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/core/DefaultLayoutGenerator.d.ts +1 -0
- package/src/nz/co/siliconst/ui5/metaui/core/DefaultLayoutGenerator.d.ts.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/core/DefaultLayoutGenerator.js +1 -1
- package/src/nz/co/siliconst/ui5/metaui/core/DefaultLayoutGenerator.js.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/core/DefaultLayoutGenerator.ts +26 -9
- package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer-dbg.js +45 -1
- package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer-dbg.js.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer.d.ts +10 -1
- package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer.d.ts.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer.js +1 -1
- package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer.js.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer.ts +45 -2
- package/src/nz/co/siliconst/ui5/metaui/layouts/CompactLayout-dbg.js +10 -6
- package/src/nz/co/siliconst/ui5/metaui/layouts/CompactLayout-dbg.js.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/layouts/CompactLayout.d.ts.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/layouts/CompactLayout.js +1 -1
- package/src/nz/co/siliconst/ui5/metaui/layouts/CompactLayout.js.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/layouts/CompactLayout.ts +5 -5
- package/src/nz/co/siliconst/ui5/metaui/layouts/FormLayout-dbg.js +10 -6
- package/src/nz/co/siliconst/ui5/metaui/layouts/FormLayout-dbg.js.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/layouts/FormLayout.d.ts.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/layouts/FormLayout.js +1 -1
- package/src/nz/co/siliconst/ui5/metaui/layouts/FormLayout.js.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/layouts/FormLayout.ts +5 -5
- package/src/nz/co/siliconst/ui5/metaui/layouts/TableLayout-dbg.js +22 -29
- package/src/nz/co/siliconst/ui5/metaui/layouts/TableLayout-dbg.js.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/layouts/TableLayout.d.ts.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/layouts/TableLayout.js +1 -1
- package/src/nz/co/siliconst/ui5/metaui/layouts/TableLayout.js.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/layouts/TableLayout.ts +18 -29
- package/src/nz/co/siliconst/ui5/metaui/layouts/WizardLayout-dbg.js +8 -4
- package/src/nz/co/siliconst/ui5/metaui/layouts/WizardLayout-dbg.js.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/layouts/WizardLayout.d.ts.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/layouts/WizardLayout.js +1 -1
- package/src/nz/co/siliconst/ui5/metaui/layouts/WizardLayout.js.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/layouts/WizardLayout.ts +3 -3
- package/src/nz/co/siliconst/ui5/metaui/library-preload.js +8 -7
- package/src/nz/co/siliconst/ui5/metaui/library-preload.js.map +1 -1
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
sap.ui.define(["sap/ui/core/Control", "./host/GeneratorHost", "../utils/Logger"], function (Control, __GeneratorHost, ___utils_Logger) {
|
|
1
|
+
sap.ui.define(["sap/ui/core/Control", "./host/GeneratorHost", "../utils/Logger", "./host/delegates/ODataDelegate"], function (Control, __GeneratorHost, ___utils_Logger, ___host_delegates_ODataDelegate) {
|
|
2
2
|
"use strict";
|
|
3
3
|
|
|
4
4
|
function _interopRequireDefault(obj) {
|
|
@@ -6,6 +6,7 @@ sap.ui.define(["sap/ui/core/Control", "./host/GeneratorHost", "../utils/Logger"]
|
|
|
6
6
|
}
|
|
7
7
|
const GeneratorHost = _interopRequireDefault(__GeneratorHost);
|
|
8
8
|
const Logger = ___utils_Logger["Logger"];
|
|
9
|
+
const ODataDelegate = ___host_delegates_ODataDelegate["ODataDelegate"];
|
|
9
10
|
/**
|
|
10
11
|
* A transparent wrapper control (Facade) that automatically chooses between Explicit Schema Mode
|
|
11
12
|
* and Inference Mode based on the presence of a 'schemaDefinition'.
|
|
@@ -19,6 +20,9 @@ sap.ui.define(["sap/ui/core/Control", "./host/GeneratorHost", "../utils/Logger"]
|
|
|
19
20
|
constructor: function constructor() {
|
|
20
21
|
Control.prototype.constructor.apply(this, arguments);
|
|
21
22
|
this._innerHost = null;
|
|
23
|
+
this.odataDelegate = null;
|
|
24
|
+
this._initializedInner = false;
|
|
25
|
+
this._innerHost = null;
|
|
22
26
|
this._initializedInner = false;
|
|
23
27
|
},
|
|
24
28
|
renderer: {
|
|
@@ -156,8 +160,40 @@ sap.ui.define(["sap/ui/core/Control", "./host/GeneratorHost", "../utils/Logger"]
|
|
|
156
160
|
* It handles the complex lifecycle task of copying all bindings, raw properties, and event listeners
|
|
157
161
|
* down to the inner host perfectly transparently.
|
|
158
162
|
*/
|
|
163
|
+
initODataDelegate: function _initODataDelegate() {
|
|
164
|
+
if (!this.odataDelegate) {
|
|
165
|
+
const oContext = this.getBindingContext("odata") || this.getBindingContext();
|
|
166
|
+
if (oContext) {
|
|
167
|
+
Logger.debug("[MetaUI DynamicHost]", `Context found for delegate initialization: ${oContext.getPath()}`, "DynamicHost");
|
|
168
|
+
if (typeof oContext.requestObject === "function" || typeof oContext.getObject === "function") {
|
|
169
|
+
Logger.debug("[MetaUI DynamicHost]", `Context supports requestObject/getObject. Instantiating ODataDelegate.`, "DynamicHost");
|
|
170
|
+
this.odataDelegate = new ODataDelegate(this, oContext);
|
|
171
|
+
this.odataDelegate.syncToEngine();
|
|
172
|
+
} else {
|
|
173
|
+
Logger.debug("[MetaUI DynamicHost]", `Context does NOT support requestObject/getObject! Keys: ${Object.keys(oContext)}`, "DynamicHost");
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
setBindingContext: function _setBindingContext(oContext, sModelName) {
|
|
179
|
+
Control.prototype.setBindingContext.call(this, oContext, sModelName);
|
|
180
|
+
this.initODataDelegate();
|
|
181
|
+
return this;
|
|
182
|
+
},
|
|
183
|
+
bindElement: function _bindElement(vPath, mParameters) {
|
|
184
|
+
Control.prototype.bindElement.call(this, vPath, mParameters);
|
|
185
|
+
const sModelName = typeof vPath === "object" ? vPath.model : undefined;
|
|
186
|
+
const oBinding = this.getElementBinding(sModelName);
|
|
187
|
+
if (oBinding) {
|
|
188
|
+
oBinding.attachChange(() => {
|
|
189
|
+
this.initODataDelegate();
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
return this;
|
|
193
|
+
},
|
|
159
194
|
onBeforeRendering: function _onBeforeRendering() {
|
|
160
195
|
Logger.debug("[MetaUI DynamicHost]", `onBeforeRendering called. _initializedInner: ${this._initializedInner}`, "DynamicHost");
|
|
196
|
+
this.initODataDelegate();
|
|
161
197
|
if (!this._initializedInner) {
|
|
162
198
|
const schema = this.getProperty("schemaDefinition");
|
|
163
199
|
const dataJson = this.getProperty("dataJson");
|
|
@@ -204,6 +240,9 @@ sap.ui.define(["sap/ui/core/Control", "./host/GeneratorHost", "../utils/Logger"]
|
|
|
204
240
|
const str = params.payloadJson || JSON.stringify(params.payload, null, 2);
|
|
205
241
|
Control.prototype.setProperty.call(this, "dataJson", str, true);
|
|
206
242
|
}
|
|
243
|
+
if (eventName === "fieldChange" && this.odataDelegate) {
|
|
244
|
+
this.odataDelegate.handleFieldChange(params.fieldPath, params.value);
|
|
245
|
+
}
|
|
207
246
|
}
|
|
208
247
|
this.fireEvent(eventName, oEvent.getParameters());
|
|
209
248
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DynamicHost-dbg.js","names":["GeneratorHost","_interopRequireDefault","__GeneratorHost","Logger","___utils_Logger","DynamicHost","Control","extend","constructor","prototype","apply","arguments","_innerHost","_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","displayMode","aggregations","_content","multiple","visibility","events","beforeSubmit","parameters","payload","addError","preventDefault","submit","payloadJson","cancel","fieldChange","fieldPath","value","validationStateChanged","validationError","message","validationSuccess","onBeforeRendering","_onBeforeRendering","debug","schema","getProperty","hasSchema","hasData","props","getMetadata","getProperties","propName","val","Control.prototype.getProperty.call","undefined","setProperty","setAggregation","getEvents","eventName","attachEvent","oEvent","params","getParameters","Control.prototype.setProperty.call","str","JSON","stringify","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\";\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 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 displayMode: { type: \"boolean\", defaultValue: false }\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 private _innerHost: GeneratorHost | null = null;\n private _initializedInner: boolean = false;\n\n /**\n * Standard UI5 Lifecycle Hook.\n * Evaluates the initial properties and spawns the appropriate inner host strategy via the HostFactory.\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 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: any) => {\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 }\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 */\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 */\n public triggerSubmit(): boolean {\n if (!this._innerHost) {\n return false;\n }\n return (this._innerHost as any).triggerSubmit();\n }\n\n /**\n * Overrides standard UI5 getProperty to transparently pull extracted data from the inner host.\n */\n public getProperty(propertyName: string): any {\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","displayMode","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","getObject","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\";\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 displayMode: { type: \"boolean\", defaultValue: false }\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 private _innerHost: GeneratorHost | null = null;\n private _initializedInner: boolean = false;\n\n /**\n * Standard UI5 Lifecycle Hook.\n * Evaluates the initial properties and spawns the appropriate inner host strategy via the HostFactory.\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 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 (typeof (oContext as any).requestObject === \"function\" || typeof (oContext as any).getObject === \"function\") {\n Logger.debug(\"[MetaUI DynamicHost]\", `Context supports requestObject/getObject. Instantiating ODataDelegate.`, \"DynamicHost\");\n this.odataDelegate = new ODataDelegate(this, oContext as any);\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 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 public bindElement(vPath: string | any, 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 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: any) => {\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 */\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 */\n public triggerSubmit(): boolean {\n if (!this._innerHost) {\n return false;\n }\n return (this._innerHost as any).triggerSubmit();\n }\n\n /**\n * Overrides standard UI5 getProperty to transparently pull extracted data from the inner host.\n */\n public getProperty(propertyName: string): any {\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":[]}
|
|
@@ -11,6 +11,9 @@ declare module "nz/co/siliconst/ui5/metaui/controls/DynamicHost" {
|
|
|
11
11
|
* @namespace nz.co.siliconst.ui5.metaui.controls
|
|
12
12
|
*/
|
|
13
13
|
export default class DynamicHost extends Control {
|
|
14
|
+
private _innerHost;
|
|
15
|
+
private odataDelegate;
|
|
16
|
+
private _initializedInner;
|
|
14
17
|
static readonly metadata: {
|
|
15
18
|
properties: {
|
|
16
19
|
schemaDefinition: {
|
|
@@ -138,6 +141,9 @@ declare module "nz/co/siliconst/ui5/metaui/controls/DynamicHost" {
|
|
|
138
141
|
* It handles the complex lifecycle task of copying all bindings, raw properties, and event listeners
|
|
139
142
|
* down to the inner host perfectly transparently.
|
|
140
143
|
*/
|
|
144
|
+
private initODataDelegate;
|
|
145
|
+
setBindingContext(oContext: sap.ui.model.Context | null | undefined, sModelName?: string): this;
|
|
146
|
+
bindElement(vPath: string | any, mParameters?: object): this;
|
|
141
147
|
onBeforeRendering(): void;
|
|
142
148
|
/**
|
|
143
149
|
* Overrides standard UI5 setProperty to act as a transparent proxy.
|
|
@@ -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;
|
|
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;IAKtD;;;;;;;;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,OAAO,CAAC,UAAU,CAA8B;QAChD,OAAO,CAAC,iBAAiB,CAAkB;QAE3C;;;;;WAKG;QACH,OAAO,CAAC,iBAAiB;QAgBlB,iBAAiB,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,GAAG,SAAS,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI;QAM/F,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI;QAY5D,iBAAiB,IAAI,IAAI;QAmEhC;;;;WAIG;QACI,WAAW,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,kBAAkB,CAAC,EAAE,OAAO,GAAG,IAAI;QAqB5F;;WAEG;QACI,YAAY,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI;QAO/F;;WAEG;QACI,aAAa,IAAI,OAAO;QAO/B;;WAEG;QACI,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,GAAG;KAMhD;CAEA"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
sap.ui.define(["sap/ui/core/Control","./host/GeneratorHost","../utils/Logger"],function(t,e,n){"use strict";function
|
|
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},displayMode:{type:"boolean",defaultValue:false}},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(typeof t.requestObject==="function"||typeof t.getObject==="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(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","DynamicHost","Control","extend","constructor","prototype","apply","this","arguments","_innerHost","_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","displayMode","aggregations","_content","multiple","visibility","events","beforeSubmit","parameters","payload","addError","preventDefault","submit","payloadJson","cancel","fieldChange","fieldPath","value","validationStateChanged","validationError","message","validationSuccess","onBeforeRendering","_onBeforeRendering","debug","schema","getProperty","hasSchema","hasData","props","getMetadata","getProperties","propName","val","Control.prototype.getProperty.call","undefined","setProperty","setAggregation","getEvents","eventName","attachEvent","oEvent","params","getParameters","Control.prototype.setProperty.call","str","JSON","stringify","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\";\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 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 displayMode: { type: \"boolean\", defaultValue: false }\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 private _innerHost: GeneratorHost | null = null;\n private _initializedInner: boolean = false;\n\n /**\n * Standard UI5 Lifecycle Hook.\n * Evaluates the initial properties and spawns the appropriate inner host strategy via the HostFactory.\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 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: any) => {\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 }\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 */\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 */\n public triggerSubmit(): boolean {\n if (!this._innerHost) {\n return false;\n }\n return (this._innerHost as any).triggerSubmit();\n }\n\n /**\n * Overrides standard UI5 getProperty to transparently pull extracted data from the inner host.\n */\n public getProperty(propertyName: string): any {\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","displayMode","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","getObject","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\";\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 displayMode: { type: \"boolean\", defaultValue: false }\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 private _innerHost: GeneratorHost | null = null;\n private _initializedInner: boolean = false;\n\n /**\n * Standard UI5 Lifecycle Hook.\n * Evaluates the initial properties and spawns the appropriate inner host strategy via the HostFactory.\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 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 (typeof (oContext as any).requestObject === \"function\" || typeof (oContext as any).getObject === \"function\") {\n Logger.debug(\"[MetaUI DynamicHost]\", `Context supports requestObject/getObject. Instantiating ODataDelegate.`, \"DynamicHost\");\n this.odataDelegate = new ODataDelegate(this, oContext as any);\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 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 public bindElement(vPath: string | any, 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 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: any) => {\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 */\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 */\n public triggerSubmit(): boolean {\n if (!this._innerHost) {\n return false;\n }\n return (this._innerHost as any).triggerSubmit();\n }\n\n /**\n * Overrides standard UI5 getProperty to transparently pull extracted data from the inner host.\n */\n public getProperty(propertyName: string): any {\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":[]}
|
|
@@ -2,6 +2,7 @@ import Control from "sap/ui/core/Control";
|
|
|
2
2
|
import RenderManager from "sap/ui/core/RenderManager";
|
|
3
3
|
import GeneratorHost from "./host/GeneratorHost";
|
|
4
4
|
import { Logger } from "../utils/Logger";
|
|
5
|
+
import { ODataDelegate } from "./host/delegates/ODataDelegate";
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* A transparent wrapper control (Facade) that automatically chooses between Explicit Schema Mode
|
|
@@ -13,6 +14,10 @@ import { Logger } from "../utils/Logger";
|
|
|
13
14
|
* @namespace nz.co.siliconst.ui5.metaui.controls
|
|
14
15
|
*/
|
|
15
16
|
export default class DynamicHost extends Control {
|
|
17
|
+
private _innerHost: GeneratorHost | null = null;
|
|
18
|
+
private odataDelegate: ODataDelegate | null = null;
|
|
19
|
+
private _initializedInner: boolean = false;
|
|
20
|
+
|
|
16
21
|
static readonly metadata = {
|
|
17
22
|
properties: {
|
|
18
23
|
schemaDefinition: { type: "any", defaultValue: null },
|
|
@@ -83,9 +88,45 @@ export default class DynamicHost extends Control {
|
|
|
83
88
|
* It handles the complex lifecycle task of copying all bindings, raw properties, and event listeners
|
|
84
89
|
* down to the inner host perfectly transparently.
|
|
85
90
|
*/
|
|
91
|
+
private initODataDelegate(): void {
|
|
92
|
+
if (!this.odataDelegate) {
|
|
93
|
+
const oContext = this.getBindingContext("odata") || this.getBindingContext();
|
|
94
|
+
if (oContext) {
|
|
95
|
+
Logger.debug("[MetaUI DynamicHost]", `Context found for delegate initialization: ${oContext.getPath()}`, "DynamicHost");
|
|
96
|
+
if (typeof (oContext as any).requestObject === "function" || typeof (oContext as any).getObject === "function") {
|
|
97
|
+
Logger.debug("[MetaUI DynamicHost]", `Context supports requestObject/getObject. Instantiating ODataDelegate.`, "DynamicHost");
|
|
98
|
+
this.odataDelegate = new ODataDelegate(this, oContext as any);
|
|
99
|
+
this.odataDelegate.syncToEngine();
|
|
100
|
+
} else {
|
|
101
|
+
Logger.debug("[MetaUI DynamicHost]", `Context does NOT support requestObject/getObject! Keys: ${Object.keys(oContext)}`, "DynamicHost");
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
public setBindingContext(oContext: sap.ui.model.Context | null | undefined, sModelName?: string): this {
|
|
108
|
+
super.setBindingContext(oContext, sModelName);
|
|
109
|
+
this.initODataDelegate();
|
|
110
|
+
return this;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
public bindElement(vPath: string | any, mParameters?: object): this {
|
|
114
|
+
super.bindElement(vPath, mParameters);
|
|
115
|
+
const sModelName = typeof vPath === "object" ? vPath.model : undefined;
|
|
116
|
+
const oBinding = this.getElementBinding(sModelName);
|
|
117
|
+
if (oBinding) {
|
|
118
|
+
oBinding.attachChange(() => {
|
|
119
|
+
this.initODataDelegate();
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
return this;
|
|
123
|
+
}
|
|
124
|
+
|
|
86
125
|
public onBeforeRendering(): void {
|
|
87
126
|
Logger.debug("[MetaUI DynamicHost]", `onBeforeRendering called. _initializedInner: ${this._initializedInner}`, "DynamicHost");
|
|
88
127
|
|
|
128
|
+
this.initODataDelegate();
|
|
129
|
+
|
|
89
130
|
if (!this._initializedInner) {
|
|
90
131
|
const schema = this.getProperty("schemaDefinition");
|
|
91
132
|
const dataJson = this.getProperty("dataJson");
|
|
@@ -135,6 +176,9 @@ export default class DynamicHost extends Control {
|
|
|
135
176
|
const str = params.payloadJson || JSON.stringify(params.payload, null, 2);
|
|
136
177
|
super.setProperty("dataJson", str, true);
|
|
137
178
|
}
|
|
179
|
+
if (eventName === "fieldChange" && this.odataDelegate) {
|
|
180
|
+
this.odataDelegate.handleFieldChange(params.fieldPath, params.value);
|
|
181
|
+
}
|
|
138
182
|
}
|
|
139
183
|
this.fireEvent(eventName, oEvent.getParameters());
|
|
140
184
|
});
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
sap.ui.define(["../../../utils/Logger"], function (_____utils_Logger) {
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
const Logger = _____utils_Logger["Logger"];
|
|
5
|
+
/**
|
|
6
|
+
* Universal OData Delegate.
|
|
7
|
+
* Natively detects and manages two-way synchronization for both OData V2 and V4 contexts
|
|
8
|
+
* without requiring controller-level mappings.
|
|
9
|
+
*/
|
|
10
|
+
class ODataDelegate {
|
|
11
|
+
odataType = null;
|
|
12
|
+
isSyncing = false;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Initializes a new instance of the ODataDelegate.
|
|
16
|
+
*
|
|
17
|
+
* @param {DynamicHost} host The parent MetaUI DynamicHost instance managing the UI generation.
|
|
18
|
+
* @param {Context} context The active UI5 Model Context bound to the host.
|
|
19
|
+
*/
|
|
20
|
+
constructor(host, context) {
|
|
21
|
+
this.host = host;
|
|
22
|
+
this.context = context;
|
|
23
|
+
this.detectODataType();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Evaluates the underlying UI5 Model bound to the context to determine if it is an
|
|
28
|
+
* OData V2 or OData V4 model. This determination drives the synchronization strategy.
|
|
29
|
+
*
|
|
30
|
+
* @private
|
|
31
|
+
*/
|
|
32
|
+
detectODataType() {
|
|
33
|
+
const model = this.context.getModel();
|
|
34
|
+
// sap.ui.model.odata.v4.ODataModel
|
|
35
|
+
// sap.ui.model.odata.v2.ODataModel
|
|
36
|
+
const sClassName = model.getMetadata().getName();
|
|
37
|
+
if (sClassName.indexOf("v4") > -1) {
|
|
38
|
+
this.odataType = "V4";
|
|
39
|
+
} else if (sClassName.indexOf("v2") > -1 || sClassName.indexOf("ODataModel") > -1) {
|
|
40
|
+
this.odataType = "V2";
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Extracts the full entity payload from the bound OData context and pushes it to the Engine.
|
|
46
|
+
* V4 uses an asynchronous requestObject(), while V2 retrieves it synchronously.
|
|
47
|
+
*
|
|
48
|
+
* @public
|
|
49
|
+
*/
|
|
50
|
+
syncToEngine() {
|
|
51
|
+
if (!this.odataType) return;
|
|
52
|
+
if (this.odataType === "V4") {
|
|
53
|
+
// V4 uses async requestObject()
|
|
54
|
+
if (typeof this.context.requestObject === "function") {
|
|
55
|
+
this.context.requestObject().then(oData => {
|
|
56
|
+
this.pushPayload(oData);
|
|
57
|
+
}).catch(err => {
|
|
58
|
+
Logger.error("[MetaUI]", "Failed to extract V4 Context payload: " + err.message, "ODataDelegate");
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
} else if (this.odataType === "V2") {
|
|
62
|
+
// V2 uses sync getObject()
|
|
63
|
+
const oData = this.context.getObject();
|
|
64
|
+
if (oData) {
|
|
65
|
+
this.pushPayload(oData);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Cleans the raw OData payload by stripping framework metadata properties (keys starting with '@' or '__')
|
|
72
|
+
* and pushes the sanitized business data into the MetaUI DynamicHost state manager.
|
|
73
|
+
*
|
|
74
|
+
* @param {any} oData The raw JSON object extracted from the OData model context.
|
|
75
|
+
* @private
|
|
76
|
+
*/
|
|
77
|
+
pushPayload(oData) {
|
|
78
|
+
if (!oData) return;
|
|
79
|
+
|
|
80
|
+
// Remove OData metadata properties before pushing to MetaUI
|
|
81
|
+
const cleanData = {
|
|
82
|
+
...oData
|
|
83
|
+
};
|
|
84
|
+
for (const key of Object.keys(cleanData)) {
|
|
85
|
+
if (key.startsWith("@") || key.startsWith("__")) {
|
|
86
|
+
delete cleanData[key];
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
this.isSyncing = true;
|
|
90
|
+
this.host.setProperty("data", cleanData);
|
|
91
|
+
this.isSyncing = false;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Intercepts a field change from the MetaUI Engine and translates it into an OData PATCH.
|
|
96
|
+
*/
|
|
97
|
+
handleFieldChange(fieldPath, value) {
|
|
98
|
+
if (this.isSyncing || !this.odataType) return;
|
|
99
|
+
try {
|
|
100
|
+
if (this.odataType === "V4") {
|
|
101
|
+
// V4 sets property directly on context
|
|
102
|
+
this.context.setProperty(fieldPath, value);
|
|
103
|
+
} else if (this.odataType === "V2") {
|
|
104
|
+
// V2 sets property on model, specifying the context path
|
|
105
|
+
const model = this.context.getModel();
|
|
106
|
+
model.setProperty(fieldPath, value, this.context);
|
|
107
|
+
}
|
|
108
|
+
if (this.host.getProperty("debugMode")) {
|
|
109
|
+
Logger.debug("[MetaUI]", `ODataDelegate Patched ${fieldPath} = ${value} via ${this.odataType}`, "ODataDelegate");
|
|
110
|
+
}
|
|
111
|
+
} catch (e) {
|
|
112
|
+
Logger.error("[MetaUI]", `Failed to patch OData context: ${e.message}`, "ODataDelegate");
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
var __exports = {
|
|
117
|
+
__esModule: true
|
|
118
|
+
};
|
|
119
|
+
__exports.ODataDelegate = ODataDelegate;
|
|
120
|
+
return __exports;
|
|
121
|
+
});
|
|
122
|
+
//# sourceMappingURL=ODataDelegate-dbg.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ODataDelegate-dbg.js","names":["Logger","_____utils_Logger","ODataDelegate","odataType","isSyncing","constructor","host","context","detectODataType","model","getModel","sClassName","getMetadata","getName","indexOf","syncToEngine","requestObject","then","oData","pushPayload","catch","err","error","message","getObject","cleanData","key","Object","keys","startsWith","setProperty","handleFieldChange","fieldPath","value","getProperty","debug","e","__exports","__esModule"],"sources":["ODataDelegate.ts"],"sourcesContent":["import { DynamicHost } from \"../DynamicHost\";\nimport Context from \"sap/ui/model/Context\";\nimport { Logger } from \"../../../utils/Logger\";\n\n/**\n * Universal OData Delegate.\n * Natively detects and manages two-way synchronization for both OData V2 and V4 contexts\n * without requiring controller-level mappings.\n */\nexport class ODataDelegate {\n private host: DynamicHost;\n private context: Context;\n private odataType: \"V2\" | \"V4\" | null = null;\n private isSyncing: boolean = false;\n\n /**\n * Initializes a new instance of the ODataDelegate.\n * \n * @param {DynamicHost} host The parent MetaUI DynamicHost instance managing the UI generation.\n * @param {Context} context The active UI5 Model Context bound to the host.\n */\n constructor(host: DynamicHost, context: Context) {\n this.host = host;\n this.context = context;\n this.detectODataType();\n }\n\n /**\n * Evaluates the underlying UI5 Model bound to the context to determine if it is an\n * OData V2 or OData V4 model. This determination drives the synchronization strategy.\n * \n * @private\n */\n private detectODataType(): void {\n const model = this.context.getModel();\n // sap.ui.model.odata.v4.ODataModel\n // sap.ui.model.odata.v2.ODataModel\n const sClassName = model.getMetadata().getName();\n if (sClassName.indexOf(\"v4\") > -1) {\n this.odataType = \"V4\";\n } else if (sClassName.indexOf(\"v2\") > -1 || sClassName.indexOf(\"ODataModel\") > -1) {\n this.odataType = \"V2\";\n }\n }\n\n /**\n * Extracts the full entity payload from the bound OData context and pushes it to the Engine.\n * V4 uses an asynchronous requestObject(), while V2 retrieves it synchronously.\n * \n * @public\n */\n public syncToEngine(): void {\n if (!this.odataType) return;\n\n if (this.odataType === \"V4\") {\n // V4 uses async requestObject()\n if (typeof (this.context as any).requestObject === \"function\") {\n (this.context as any).requestObject().then((oData: any) => {\n this.pushPayload(oData);\n }).catch((err: Error) => {\n Logger.error(\"[MetaUI]\", \"Failed to extract V4 Context payload: \" + err.message, \"ODataDelegate\");\n });\n }\n } else if (this.odataType === \"V2\") {\n // V2 uses sync getObject()\n const oData = this.context.getObject();\n if (oData) {\n this.pushPayload(oData);\n }\n }\n }\n\n /**\n * Cleans the raw OData payload by stripping framework metadata properties (keys starting with '@' or '__')\n * and pushes the sanitized business data into the MetaUI DynamicHost state manager.\n * \n * @param {any} oData The raw JSON object extracted from the OData model context.\n * @private\n */\n private pushPayload(oData: any): void {\n if (!oData) return;\n \n // Remove OData metadata properties before pushing to MetaUI\n const cleanData = { ...oData };\n for (const key of Object.keys(cleanData)) {\n if (key.startsWith(\"@\") || key.startsWith(\"__\")) {\n delete cleanData[key];\n }\n }\n\n this.isSyncing = true;\n this.host.setProperty(\"data\", cleanData);\n this.isSyncing = false;\n }\n\n /**\n * Intercepts a field change from the MetaUI Engine and translates it into an OData PATCH.\n */\n public handleFieldChange(fieldPath: string, value: any): void {\n if (this.isSyncing || !this.odataType) return;\n\n try {\n if (this.odataType === \"V4\") {\n // V4 sets property directly on context\n this.context.setProperty(fieldPath, value);\n } else if (this.odataType === \"V2\") {\n // V2 sets property on model, specifying the context path\n const model = this.context.getModel();\n model.setProperty(fieldPath, value, this.context);\n }\n if (this.host.getProperty(\"debugMode\")) {\n Logger.debug(\"[MetaUI]\", `ODataDelegate Patched ${fieldPath} = ${value} via ${this.odataType}`, \"ODataDelegate\");\n }\n } catch (e) {\n Logger.error(\"[MetaUI]\", `Failed to patch OData context: ${(e as Error).message}`, \"ODataDelegate\");\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
declare module "nz/co/siliconst/ui5/metaui/controls/host/delegates/ODataDelegate" {
|
|
2
|
+
import { DynamicHost } from "nz/co/siliconst/ui5/metaui/controls/host/DynamicHost";
|
|
3
|
+
import Context from "sap/ui/model/Context";
|
|
4
|
+
/**
|
|
5
|
+
* Universal OData Delegate.
|
|
6
|
+
* Natively detects and manages two-way synchronization for both OData V2 and V4 contexts
|
|
7
|
+
* without requiring controller-level mappings.
|
|
8
|
+
*/
|
|
9
|
+
export class ODataDelegate {
|
|
10
|
+
private host;
|
|
11
|
+
private context;
|
|
12
|
+
private odataType;
|
|
13
|
+
private isSyncing;
|
|
14
|
+
/**
|
|
15
|
+
* Initializes a new instance of the ODataDelegate.
|
|
16
|
+
*
|
|
17
|
+
* @param {DynamicHost} host The parent MetaUI DynamicHost instance managing the UI generation.
|
|
18
|
+
* @param {Context} context The active UI5 Model Context bound to the host.
|
|
19
|
+
*/
|
|
20
|
+
constructor(host: DynamicHost, context: Context);
|
|
21
|
+
/**
|
|
22
|
+
* Evaluates the underlying UI5 Model bound to the context to determine if it is an
|
|
23
|
+
* OData V2 or OData V4 model. This determination drives the synchronization strategy.
|
|
24
|
+
*
|
|
25
|
+
* @private
|
|
26
|
+
*/
|
|
27
|
+
private detectODataType;
|
|
28
|
+
/**
|
|
29
|
+
* Extracts the full entity payload from the bound OData context and pushes it to the Engine.
|
|
30
|
+
* V4 uses an asynchronous requestObject(), while V2 retrieves it synchronously.
|
|
31
|
+
*
|
|
32
|
+
* @public
|
|
33
|
+
*/
|
|
34
|
+
syncToEngine(): void;
|
|
35
|
+
/**
|
|
36
|
+
* Cleans the raw OData payload by stripping framework metadata properties (keys starting with '@' or '__')
|
|
37
|
+
* and pushes the sanitized business data into the MetaUI DynamicHost state manager.
|
|
38
|
+
*
|
|
39
|
+
* @param {any} oData The raw JSON object extracted from the OData model context.
|
|
40
|
+
* @private
|
|
41
|
+
*/
|
|
42
|
+
private pushPayload;
|
|
43
|
+
/**
|
|
44
|
+
* Intercepts a field change from the MetaUI Engine and translates it into an OData PATCH.
|
|
45
|
+
*/
|
|
46
|
+
handleFieldChange(fieldPath: string, value: any): void;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=ODataDelegate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ODataDelegate.d.ts","sourceRoot":"../../../../../../../../../..","sources":["src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ODataDelegate.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,kEAAkE,CAAC;IAClF,OAAO,EAAE,WAAW,EAAE,MAAM,sDAAsD,CAAC;IACnF,OAAO,OAAO,MAAM,sBAAsB,CAAC;IAG3C;;;;OAIG;IACH,MAAa,aAAa;QACtB,OAAO,CAAC,IAAI,CAAc;QAC1B,OAAO,CAAC,OAAO,CAAU;QACzB,OAAO,CAAC,SAAS,CAA4B;QAC7C,OAAO,CAAC,SAAS,CAAkB;QAEnC;;;;;WAKG;oBACS,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO;QAM/C;;;;;WAKG;QACH,OAAO,CAAC,eAAe;QAYvB;;;;;WAKG;QACI,YAAY,IAAI,IAAI;QAqB3B;;;;;;WAMG;QACH,OAAO,CAAC,WAAW;QAgBnB;;WAEG;QACI,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI;KAmBhE;CAEA"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
sap.ui.define(["../../../utils/Logger"],function(t){"use strict";const e=t["Logger"];class a{odataType=null;isSyncing=false;constructor(t,e){this.host=t;this.context=e;this.detectODataType()}detectODataType(){const t=this.context.getModel();const e=t.getMetadata().getName();if(e.indexOf("v4")>-1){this.odataType="V4"}else if(e.indexOf("v2")>-1||e.indexOf("ODataModel")>-1){this.odataType="V2"}}syncToEngine(){if(!this.odataType)return;if(this.odataType==="V4"){if(typeof this.context.requestObject==="function"){this.context.requestObject().then(t=>{this.pushPayload(t)}).catch(t=>{e.error("[MetaUI]","Failed to extract V4 Context payload: "+t.message,"ODataDelegate")})}}else if(this.odataType==="V2"){const t=this.context.getObject();if(t){this.pushPayload(t)}}}pushPayload(t){if(!t)return;const e={...t};for(const t of Object.keys(e)){if(t.startsWith("@")||t.startsWith("__")){delete e[t]}}this.isSyncing=true;this.host.setProperty("data",e);this.isSyncing=false}handleFieldChange(t,a){if(this.isSyncing||!this.odataType)return;try{if(this.odataType==="V4"){this.context.setProperty(t,a)}else if(this.odataType==="V2"){const e=this.context.getModel();e.setProperty(t,a,this.context)}if(this.host.getProperty("debugMode")){e.debug("[MetaUI]",`ODataDelegate Patched ${t} = ${a} via ${this.odataType}`,"ODataDelegate")}}catch(t){e.error("[MetaUI]",`Failed to patch OData context: ${t.message}`,"ODataDelegate")}}}var s={__esModule:true};s.ODataDelegate=a;return s});
|
|
2
|
+
//# sourceMappingURL=ODataDelegate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ODataDelegate.js","names":["Logger","_____utils_Logger","ODataDelegate","odataType","isSyncing","constructor","host","context","this","detectODataType","model","getModel","sClassName","getMetadata","getName","indexOf","syncToEngine","requestObject","then","oData","pushPayload","catch","err","error","message","getObject","cleanData","key","Object","keys","startsWith","setProperty","handleFieldChange","fieldPath","value","getProperty","debug","e","__exports","__esModule"],"sources":["ODataDelegate.ts"],"sourcesContent":["import { DynamicHost } from \"../DynamicHost\";\nimport Context from \"sap/ui/model/Context\";\nimport { Logger } from \"../../../utils/Logger\";\n\n/**\n * Universal OData Delegate.\n * Natively detects and manages two-way synchronization for both OData V2 and V4 contexts\n * without requiring controller-level mappings.\n */\nexport class ODataDelegate {\n private host: DynamicHost;\n private context: Context;\n private odataType: \"V2\" | \"V4\" | null = null;\n private isSyncing: boolean = false;\n\n /**\n * Initializes a new instance of the ODataDelegate.\n * \n * @param {DynamicHost} host The parent MetaUI DynamicHost instance managing the UI generation.\n * @param {Context} context The active UI5 Model Context bound to the host.\n */\n constructor(host: DynamicHost, context: Context) {\n this.host = host;\n this.context = context;\n this.detectODataType();\n }\n\n /**\n * Evaluates the underlying UI5 Model bound to the context to determine if it is an\n * OData V2 or OData V4 model. This determination drives the synchronization strategy.\n * \n * @private\n */\n private detectODataType(): void {\n const model = this.context.getModel();\n // sap.ui.model.odata.v4.ODataModel\n // sap.ui.model.odata.v2.ODataModel\n const sClassName = model.getMetadata().getName();\n if (sClassName.indexOf(\"v4\") > -1) {\n this.odataType = \"V4\";\n } else if (sClassName.indexOf(\"v2\") > -1 || sClassName.indexOf(\"ODataModel\") > -1) {\n this.odataType = \"V2\";\n }\n }\n\n /**\n * Extracts the full entity payload from the bound OData context and pushes it to the Engine.\n * V4 uses an asynchronous requestObject(), while V2 retrieves it synchronously.\n * \n * @public\n */\n public syncToEngine(): void {\n if (!this.odataType) return;\n\n if (this.odataType === \"V4\") {\n // V4 uses async requestObject()\n if (typeof (this.context as any).requestObject === \"function\") {\n (this.context as any).requestObject().then((oData: any) => {\n this.pushPayload(oData);\n }).catch((err: Error) => {\n Logger.error(\"[MetaUI]\", \"Failed to extract V4 Context payload: \" + err.message, \"ODataDelegate\");\n });\n }\n } else if (this.odataType === \"V2\") {\n // V2 uses sync getObject()\n const oData = this.context.getObject();\n if (oData) {\n this.pushPayload(oData);\n }\n }\n }\n\n /**\n * Cleans the raw OData payload by stripping framework metadata properties (keys starting with '@' or '__')\n * and pushes the sanitized business data into the MetaUI DynamicHost state manager.\n * \n * @param {any} oData The raw JSON object extracted from the OData model context.\n * @private\n */\n private pushPayload(oData: any): void {\n if (!oData) return;\n \n // Remove OData metadata properties before pushing to MetaUI\n const cleanData = { ...oData };\n for (const key of Object.keys(cleanData)) {\n if (key.startsWith(\"@\") || key.startsWith(\"__\")) {\n delete cleanData[key];\n }\n }\n\n this.isSyncing = true;\n this.host.setProperty(\"data\", cleanData);\n this.isSyncing = false;\n }\n\n /**\n * Intercepts a field change from the MetaUI Engine and translates it into an OData PATCH.\n */\n public handleFieldChange(fieldPath: string, value: any): void {\n if (this.isSyncing || !this.odataType) return;\n\n try {\n if (this.odataType === \"V4\") {\n // V4 sets property directly on context\n this.context.setProperty(fieldPath, value);\n } else if (this.odataType === \"V2\") {\n // V2 sets property on model, specifying the context path\n const model = this.context.getModel();\n model.setProperty(fieldPath, value, this.context);\n }\n if (this.host.getProperty(\"debugMode\")) {\n Logger.debug(\"[MetaUI]\", `ODataDelegate Patched ${fieldPath} = ${value} via ${this.odataType}`, \"ODataDelegate\");\n }\n } catch (e) {\n Logger.error(\"[MetaUI]\", `Failed to patch OData context: ${(e as Error).message}`, \"ODataDelegate\");\n }\n }\n}\n"],"mappings":"uEAESA,EAAMC,EAAA,UAOR,MAAMC,EAGDC,UAAgC,KAChCC,UAAqB,MAQ7BC,YAAYC,EAAmBC,GAC3BC,KAAKF,KAAOA,EACZE,KAAKD,QAAUA,EACfC,KAAKC,iBACT,CAQQA,kBACJ,MAAMC,EAAQF,KAAKD,QAAQI,WAG3B,MAAMC,EAAaF,EAAMG,cAAcC,UACvC,GAAIF,EAAWG,QAAQ,OAAS,EAAG,CAC/BP,KAAKL,UAAY,IACrB,MAAO,GAAIS,EAAWG,QAAQ,OAAS,GAAKH,EAAWG,QAAQ,eAAiB,EAAG,CAC/EP,KAAKL,UAAY,IACrB,CACJ,CAQOa,eACH,IAAKR,KAAKL,UAAW,OAErB,GAAIK,KAAKL,YAAc,KAAM,CAEzB,UAAYK,KAAKD,QAAgBU,gBAAkB,WAAY,CAC1DT,KAAKD,QAAgBU,gBAAgBC,KAAMC,IACxCX,KAAKY,YAAYD,KAClBE,MAAOC,IACNtB,EAAOuB,MAAM,WAAY,yCAA2CD,EAAIE,QAAS,kBAEzF,CACJ,MAAO,GAAIhB,KAAKL,YAAc,KAAM,CAEhC,MAAMgB,EAAQX,KAAKD,QAAQkB,YAC3B,GAAIN,EAAO,CACPX,KAAKY,YAAYD,EACrB,CACJ,CACJ,CASQC,YAAYD,GAChB,IAAKA,EAAO,OAGZ,MAAMO,EAAY,IAAKP,GACvB,IAAK,MAAMQ,KAAOC,OAAOC,KAAKH,GAAY,CACtC,GAAIC,EAAIG,WAAW,MAAQH,EAAIG,WAAW,MAAO,QACtCJ,EAAUC,EACrB,CACJ,CAEAnB,KAAKJ,UAAY,KACjBI,KAAKF,KAAKyB,YAAY,OAAQL,GAC9BlB,KAAKJ,UAAY,KACrB,CAKO4B,kBAAkBC,EAAmBC,GACxC,GAAI1B,KAAKJ,YAAcI,KAAKL,UAAW,OAEvC,IACI,GAAIK,KAAKL,YAAc,KAAM,CAEzBK,KAAKD,QAAQwB,YAAYE,EAAWC,EACxC,MAAO,GAAI1B,KAAKL,YAAc,KAAM,CAEhC,MAAMO,EAAQF,KAAKD,QAAQI,WAC3BD,EAAMqB,YAAYE,EAAWC,EAAO1B,KAAKD,QAC7C,CACA,GAAIC,KAAKF,KAAK6B,YAAY,aAAc,CACpCnC,EAAOoC,MAAM,WAAY,yBAAyBH,OAAeC,SAAa1B,KAAKL,YAAa,gBACpG,CACJ,CAAE,MAAOkC,GACLrC,EAAOuB,MAAM,WAAY,kCAAmCc,EAAYb,UAAW,gBACvF,CACJ,EACH,IAAAc,EAAA,CAAAC,WAAA,MAAAD,EAAApC,gBAAA,OAAAoC,CAAA","ignoreList":[]}
|