@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.
Files changed (55) hide show
  1. package/package.json +1 -1
  2. package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost-dbg.js +40 -1
  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 +6 -0
  5. package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost.d.ts.map +1 -1
  6. package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost.js +1 -1
  7. package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost.js.map +1 -1
  8. package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost.ts +44 -0
  9. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ODataDelegate-dbg.js +122 -0
  10. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ODataDelegate-dbg.js.map +1 -0
  11. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ODataDelegate.d.ts +49 -0
  12. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ODataDelegate.d.ts.map +1 -0
  13. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ODataDelegate.js +2 -0
  14. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ODataDelegate.js.map +1 -0
  15. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ODataDelegate.ts +118 -0
  16. package/src/nz/co/siliconst/ui5/metaui/core/DefaultLayoutGenerator-dbg.js +24 -8
  17. package/src/nz/co/siliconst/ui5/metaui/core/DefaultLayoutGenerator-dbg.js.map +1 -1
  18. package/src/nz/co/siliconst/ui5/metaui/core/DefaultLayoutGenerator.d.ts +1 -0
  19. package/src/nz/co/siliconst/ui5/metaui/core/DefaultLayoutGenerator.d.ts.map +1 -1
  20. package/src/nz/co/siliconst/ui5/metaui/core/DefaultLayoutGenerator.js +1 -1
  21. package/src/nz/co/siliconst/ui5/metaui/core/DefaultLayoutGenerator.js.map +1 -1
  22. package/src/nz/co/siliconst/ui5/metaui/core/DefaultLayoutGenerator.ts +26 -9
  23. package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer-dbg.js +45 -1
  24. package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer-dbg.js.map +1 -1
  25. package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer.d.ts +10 -1
  26. package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer.d.ts.map +1 -1
  27. package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer.js +1 -1
  28. package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer.js.map +1 -1
  29. package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer.ts +45 -2
  30. package/src/nz/co/siliconst/ui5/metaui/layouts/CompactLayout-dbg.js +10 -6
  31. package/src/nz/co/siliconst/ui5/metaui/layouts/CompactLayout-dbg.js.map +1 -1
  32. package/src/nz/co/siliconst/ui5/metaui/layouts/CompactLayout.d.ts.map +1 -1
  33. package/src/nz/co/siliconst/ui5/metaui/layouts/CompactLayout.js +1 -1
  34. package/src/nz/co/siliconst/ui5/metaui/layouts/CompactLayout.js.map +1 -1
  35. package/src/nz/co/siliconst/ui5/metaui/layouts/CompactLayout.ts +5 -5
  36. package/src/nz/co/siliconst/ui5/metaui/layouts/FormLayout-dbg.js +10 -6
  37. package/src/nz/co/siliconst/ui5/metaui/layouts/FormLayout-dbg.js.map +1 -1
  38. package/src/nz/co/siliconst/ui5/metaui/layouts/FormLayout.d.ts.map +1 -1
  39. package/src/nz/co/siliconst/ui5/metaui/layouts/FormLayout.js +1 -1
  40. package/src/nz/co/siliconst/ui5/metaui/layouts/FormLayout.js.map +1 -1
  41. package/src/nz/co/siliconst/ui5/metaui/layouts/FormLayout.ts +5 -5
  42. package/src/nz/co/siliconst/ui5/metaui/layouts/TableLayout-dbg.js +22 -29
  43. package/src/nz/co/siliconst/ui5/metaui/layouts/TableLayout-dbg.js.map +1 -1
  44. package/src/nz/co/siliconst/ui5/metaui/layouts/TableLayout.d.ts.map +1 -1
  45. package/src/nz/co/siliconst/ui5/metaui/layouts/TableLayout.js +1 -1
  46. package/src/nz/co/siliconst/ui5/metaui/layouts/TableLayout.js.map +1 -1
  47. package/src/nz/co/siliconst/ui5/metaui/layouts/TableLayout.ts +18 -29
  48. package/src/nz/co/siliconst/ui5/metaui/layouts/WizardLayout-dbg.js +8 -4
  49. package/src/nz/co/siliconst/ui5/metaui/layouts/WizardLayout-dbg.js.map +1 -1
  50. package/src/nz/co/siliconst/ui5/metaui/layouts/WizardLayout.d.ts.map +1 -1
  51. package/src/nz/co/siliconst/ui5/metaui/layouts/WizardLayout.js +1 -1
  52. package/src/nz/co/siliconst/ui5/metaui/layouts/WizardLayout.js.map +1 -1
  53. package/src/nz/co/siliconst/ui5/metaui/layouts/WizardLayout.ts +3 -3
  54. package/src/nz/co/siliconst/ui5/metaui/library-preload.js +8 -7
  55. package/src/nz/co/siliconst/ui5/metaui/library-preload.js.map +1 -1
@@ -177,10 +177,9 @@ export class SchemaNormalizer {
177
177
  const val = obj[key];
178
178
  if (val === null || val === undefined) continue;
179
179
 
180
- if (typeof val === "object" && !Array.isArray(val)) continue;
181
-
182
180
  let type: FieldType = "string";
183
181
  let items: IPropertyMetadata | undefined;
182
+ let nestedProps: Record<string, IPropertyMetadata> | undefined;
184
183
 
185
184
  if (typeof val === "number") type = "number";
186
185
  else if (typeof val === "boolean") type = "boolean";
@@ -190,11 +189,15 @@ export class SchemaNormalizer {
190
189
  type: "object",
191
190
  properties: val.length > 0 ? this.inferPropertiesFromObject(val[0]) : {}
192
191
  };
192
+ } else if (typeof val === "object") {
193
+ type = "object";
194
+ nestedProps = this.inferPropertiesFromObject(val);
193
195
  }
194
196
 
195
197
  properties[key] = {
196
198
  type,
197
199
  items,
200
+ properties: nestedProps,
198
201
  ui: {
199
202
  label: this.generateLabel(key),
200
203
  isKey: false,
@@ -205,4 +208,44 @@ export class SchemaNormalizer {
205
208
 
206
209
  return properties;
207
210
  }
211
+
212
+ /**
213
+ * Resolves a JSON Schema scope (e.g. '#/properties/header/properties/id')
214
+ * against the ISchema, returning the PropertyMetadata and the UI5 binding path.
215
+ */
216
+ public static resolveScope(schema: ISchema, scope: string): { meta: IPropertyMetadata | undefined, bindingPath: string, propKey: string } {
217
+ if (!scope || !scope.startsWith("#/properties/")) {
218
+ return { meta: undefined, bindingPath: scope || "", propKey: scope || "" };
219
+ }
220
+
221
+ const pathSegments = scope.replace("#/properties/", "").split("/properties/");
222
+ let current: any = schema.properties;
223
+ let meta: IPropertyMetadata | undefined;
224
+
225
+ Logger.debug("[MetaUI SchemaNormalizer]", `Resolving scope '${scope}' with segments: ${JSON.stringify(pathSegments)}`, "SchemaNormalizer");
226
+ Logger.debug("[MetaUI SchemaNormalizer]", `Root schema keys: ${Object.keys(schema.properties || {})}`, "SchemaNormalizer");
227
+
228
+ for (let i = 0; i < pathSegments.length; i++) {
229
+ const segment = pathSegments[i];
230
+ if (!current) {
231
+ Logger.debug("[MetaUI SchemaNormalizer]", `current is undefined at segment '${segment}'`, "SchemaNormalizer");
232
+ meta = undefined;
233
+ break;
234
+ }
235
+ meta = current[segment];
236
+ Logger.debug("[MetaUI SchemaNormalizer]", `Segment '${segment}' resolved to meta: ${!!meta}. Available keys in current: ${Object.keys(current)}`, "SchemaNormalizer");
237
+ if (i < pathSegments.length - 1) {
238
+ current = meta?.properties;
239
+ }
240
+ }
241
+
242
+ const bindingPath = pathSegments.join("/");
243
+ const propKey = scope.replace("#/properties/", ""); // The original raw string for logging
244
+
245
+ return {
246
+ meta,
247
+ bindingPath,
248
+ propKey
249
+ };
250
+ }
208
251
  }
@@ -1,6 +1,7 @@
1
- sap.ui.define(["sap/m/VBox", "sap/m/Label", "../utils/Logger"], function (VBox, Label, ___utils_Logger) {
1
+ sap.ui.define(["sap/m/VBox", "sap/m/Label", "../core/SchemaNormalizer", "../utils/Logger"], function (VBox, Label, ___core_SchemaNormalizer, ___utils_Logger) {
2
2
  "use strict";
3
3
 
4
+ const SchemaNormalizer = ___core_SchemaNormalizer["SchemaNormalizer"];
4
5
  const Logger = ___utils_Logger["Logger"];
5
6
  /**
6
7
  * Layout Manager responsible for generating a dense, lightweight layout (no SimpleForm padding).
@@ -49,8 +50,11 @@ sap.ui.define(["sap/m/VBox", "sap/m/Label", "../utils/Logger"], function (VBox,
49
50
  Logger.error(`[MetaUI] Invalid scope '${element.scope}' in uiLayout Control.`, "", "CompactLayout");
50
51
  return;
51
52
  }
52
- const propKey = element.scope.replace("#/properties/", "");
53
- const meta = schema.properties?.[propKey];
53
+ const {
54
+ meta,
55
+ bindingPath,
56
+ propKey
57
+ } = SchemaNormalizer.resolveScope(schema, element.scope);
54
58
  if (!meta) {
55
59
  Logger.error(`[MetaUI] Property '${propKey}' not found in schema definitions.`, "", "CompactLayout");
56
60
  return;
@@ -61,13 +65,13 @@ sap.ui.define(["sap/m/VBox", "sap/m/Label", "../utils/Logger"], function (VBox,
61
65
  if (isSubLayout) {
62
66
  Logger.debug("[MetaUI CompactLayout]", `Routing property '${propKey}' to Table Sub-Layout.`, "CompactLayout");
63
67
  tableElements.push({
64
- scope: propKey,
68
+ scope: bindingPath,
65
69
  meta,
66
70
  label: element.label
67
71
  });
68
72
  } else {
69
- Logger.debug("[MetaUI CompactLayout]", `Rendering scalar field '${propKey}'.`, "CompactLayout");
70
- this._renderScalarField(container, element, propKey, meta, modelName, engine);
73
+ Logger.debug("[MetaUI CompactLayout]", `Rendering scalar field '${bindingPath}'.`, "CompactLayout");
74
+ this._renderScalarField(container, element, bindingPath, meta, modelName, engine);
71
75
  }
72
76
  } else {
73
77
  Logger.warn(`[MetaUI] Unsupported layout element type '${element.type}'.`, "", "CompactLayout");
@@ -1 +1 @@
1
- {"version":3,"file":"CompactLayout-dbg.js","names":["Logger","___utils_Logger","CompactLayout","render","schema","modelName","engine","onSubmit","container","VBox","renderType","addStyleClass","uiLayout","Array","isArray","warn","tableElements","renderElement","element","type","label","title","sap","m","Title","text","level","addItem","elements","forEach","scope","startsWith","error","propKey","replace","meta","properties","isCollectionOfRecords","items","hasExplicitWidget","ui","widget","isSubLayout","debug","push","_renderScalarField","field","subSchema","control","generateLayout","msg","message","showErrorPopup","labelText","Label","required","effectiveMeta","generateField","fieldBox","__exports","__esModule"],"sources":["CompactLayout.ts"],"sourcesContent":["/**\n * @file CompactLayout.ts\n * @description Generates a lightweight, dense VBox layout for use inside tight spaces like table cells.\n */\n\nimport VBox from \"sap/m/VBox\";\nimport Label from \"sap/m/Label\";\nimport Title from \"sap/ui/core/Title\";\nimport { IPropertyMetadata, ISchema, ILayoutElement } from \"../interfaces/ISchema\";\nimport { ILayoutManager } from \"../interfaces/ILayoutManager\";\nimport { Engine } from \"../core/Engine\";\nimport { Logger } from \"../utils/Logger\";\nimport Control from \"sap/ui/core/Control\";\n\n/**\n * Layout Manager responsible for generating a dense, lightweight layout (no SimpleForm padding).\n * Ideal for rendering objects dynamically inside table cells or side-panels.\n * \n * @namespace nz.co.siliconst.ui5.metaui.layouts\n * @public\n */\nexport class CompactLayout implements ILayoutManager {\n /**\n * Renders the JSON Schema properties into a dense VBox layout.\n * \n * @param schema The active JSON schema subset.\n * @param modelName The bound UI5 model name.\n * @param engine The central orchestrator for delegating plugin generation.\n * @param onSubmit Optional submit hook.\n * @returns {Control} The VBox wrapper containing the generated compact form.\n */\n public render(schema: ISchema, modelName: string, engine: Engine, onSubmit?: () => void): Control {\n const container = new VBox({ renderType: \"Bare\" });\n container.addStyleClass(\"sapUiTinyMargin\");\n\n if (!schema.uiLayout || !Array.isArray(schema.uiLayout)) {\n Logger.warn(\"[MetaUI] Missing 'uiLayout' array in schema. CompactLayout will not render any fields.\");\n return container;\n }\n\n const tableElements: { scope: string, meta: IPropertyMetadata, label?: string }[] = [];\n\n // Recursively render layout elements\n const renderElement = (element: ILayoutElement) => {\n if (element.type === \"Group\") {\n if (element.label) {\n const title = new sap.m.Title({ text: element.label, level: \"H5\" });\n title.addStyleClass(\"sapUiTinyMarginTop sapUiTinyMarginBottom\");\n container.addItem(title);\n }\n \n if (element.elements && Array.isArray(element.elements)) {\n element.elements.forEach(renderElement);\n }\n } else if (element.type === \"Control\") {\n if (!element.scope || !element.scope.startsWith(\"#/properties/\")) {\n Logger.error(`[MetaUI] Invalid scope '${element.scope}' in uiLayout Control.`, \"\", \"CompactLayout\");\n return;\n }\n \n const propKey = element.scope.replace(\"#/properties/\", \"\");\n const meta = schema.properties?.[propKey];\n \n if (!meta) {\n Logger.error(`[MetaUI] Property '${propKey}' not found in schema definitions.`, \"\", \"CompactLayout\");\n return;\n }\n\n const isCollectionOfRecords = meta.items?.type === \"object\" || meta.items?.properties;\n const hasExplicitWidget = !!meta.ui?.widget;\n const isSubLayout = meta.type === \"array\" && isCollectionOfRecords && !hasExplicitWidget;\n\n if (isSubLayout) {\n Logger.debug(\"[MetaUI CompactLayout]\", `Routing property '${propKey}' to Table Sub-Layout.`, \"CompactLayout\");\n tableElements.push({ scope: propKey, meta, label: element.label });\n } else {\n Logger.debug(\"[MetaUI CompactLayout]\", `Rendering scalar field '${propKey}'.`, \"CompactLayout\");\n this._renderScalarField(container, element, propKey, meta, modelName, engine);\n }\n } else {\n Logger.warn(`[MetaUI] Unsupported layout element type '${element.type}'.`, \"\", \"CompactLayout\");\n }\n };\n\n // Render everything defined in the layout\n schema.uiLayout.forEach(renderElement);\n\n // Render array/table sub-layouts full width below the fields\n tableElements.forEach(field => {\n try {\n const subSchema = {\n type: \"array\",\n title: field.label || field.meta.ui?.label || field.scope,\n items: field.meta.items || { type: \"object\", properties: {} },\n uiLayout: field.meta.items?.uiLayout\n };\n \n const control = engine.generateLayout(subSchema as ISchema, modelName, `/${field.scope}`);\n if (control) {\n control.addStyleClass(\"sapUiTinyMarginTop\");\n container.addItem(control);\n }\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI] Failed to render array field ${field.scope}`, msg, \"CompactLayout\");\n Logger.showErrorPopup(`Failed to render array field '${field.scope}'.\\n\\nDetails: ${msg}`);\n }\n });\n\n return container;\n }\n\n private _renderScalarField(container: VBox, element: ILayoutElement, propKey: string, meta: IPropertyMetadata, modelName: string, engine: Engine): void {\n try {\n const labelText = element.label || meta.ui?.label || propKey;\n const label = new Label({\n text: labelText,\n required: meta.required\n });\n label.addStyleClass(\"sapUiTinyMarginTop\");\n\n const effectiveMeta = { ...meta };\n if (element.widget) {\n effectiveMeta.ui = { ...meta.ui, widget: element.widget };\n }\n\n const control = engine.generateField(effectiveMeta, `/${propKey}`, modelName);\n control.addStyleClass(\"sapUiTinyMarginBottom\");\n\n // Wrap label and field tightly\n const fieldBox = new VBox({ renderType: \"Bare\", items: [label, control] });\n container.addItem(fieldBox);\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI] Failed to render field ${propKey}`, msg, \"CompactLayout\");\n Logger.showErrorPopup(`Failed to render field '${propKey}'.\\n\\nDetails: ${msg}`);\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"CompactLayout-dbg.js","names":["SchemaNormalizer","___core_SchemaNormalizer","Logger","___utils_Logger","CompactLayout","render","schema","modelName","engine","onSubmit","container","VBox","renderType","addStyleClass","uiLayout","Array","isArray","warn","tableElements","renderElement","element","type","label","title","sap","m","Title","text","level","addItem","elements","forEach","scope","startsWith","error","meta","bindingPath","propKey","resolveScope","isCollectionOfRecords","items","properties","hasExplicitWidget","ui","widget","isSubLayout","debug","push","_renderScalarField","field","subSchema","control","generateLayout","msg","message","showErrorPopup","labelText","Label","required","effectiveMeta","generateField","fieldBox","__exports","__esModule"],"sources":["CompactLayout.ts"],"sourcesContent":["/**\n * @file CompactLayout.ts\n * @description Generates a lightweight, dense VBox layout for use inside tight spaces like table cells.\n */\n\nimport VBox from \"sap/m/VBox\";\nimport Label from \"sap/m/Label\";\nimport Title from \"sap/ui/core/Title\";\nimport { IPropertyMetadata, ISchema, ILayoutElement } from \"../interfaces/ISchema\";\nimport { ILayoutManager } from \"../interfaces/ILayoutManager\";\nimport { Engine } from \"../core/Engine\";\nimport { SchemaNormalizer } from \"../core/SchemaNormalizer\";\nimport { Logger } from \"../utils/Logger\";\nimport Control from \"sap/ui/core/Control\";\n\n/**\n * Layout Manager responsible for generating a dense, lightweight layout (no SimpleForm padding).\n * Ideal for rendering objects dynamically inside table cells or side-panels.\n * \n * @namespace nz.co.siliconst.ui5.metaui.layouts\n * @public\n */\nexport class CompactLayout implements ILayoutManager {\n /**\n * Renders the JSON Schema properties into a dense VBox layout.\n * \n * @param schema The active JSON schema subset.\n * @param modelName The bound UI5 model name.\n * @param engine The central orchestrator for delegating plugin generation.\n * @param onSubmit Optional submit hook.\n * @returns {Control} The VBox wrapper containing the generated compact form.\n */\n public render(schema: ISchema, modelName: string, engine: Engine, onSubmit?: () => void): Control {\n const container = new VBox({ renderType: \"Bare\" });\n container.addStyleClass(\"sapUiTinyMargin\");\n\n if (!schema.uiLayout || !Array.isArray(schema.uiLayout)) {\n Logger.warn(\"[MetaUI] Missing 'uiLayout' array in schema. CompactLayout will not render any fields.\");\n return container;\n }\n\n const tableElements: { scope: string, meta: IPropertyMetadata, label?: string }[] = [];\n\n // Recursively render layout elements\n const renderElement = (element: ILayoutElement) => {\n if (element.type === \"Group\") {\n if (element.label) {\n const title = new sap.m.Title({ text: element.label, level: \"H5\" });\n title.addStyleClass(\"sapUiTinyMarginTop sapUiTinyMarginBottom\");\n container.addItem(title);\n }\n \n if (element.elements && Array.isArray(element.elements)) {\n element.elements.forEach(renderElement);\n }\n } else if (element.type === \"Control\") {\n if (!element.scope || !element.scope.startsWith(\"#/properties/\")) {\n Logger.error(`[MetaUI] Invalid scope '${element.scope}' in uiLayout Control.`, \"\", \"CompactLayout\");\n return;\n }\n \n const { meta, bindingPath, propKey } = SchemaNormalizer.resolveScope(schema, element.scope);\n \n if (!meta) {\n Logger.error(`[MetaUI] Property '${propKey}' not found in schema definitions.`, \"\", \"CompactLayout\");\n return;\n }\n\n const isCollectionOfRecords = meta.items?.type === \"object\" || meta.items?.properties;\n const hasExplicitWidget = !!meta.ui?.widget;\n const isSubLayout = meta.type === \"array\" && isCollectionOfRecords && !hasExplicitWidget;\n\n if (isSubLayout) {\n Logger.debug(\"[MetaUI CompactLayout]\", `Routing property '${propKey}' to Table Sub-Layout.`, \"CompactLayout\");\n tableElements.push({ scope: bindingPath, meta, label: element.label });\n } else {\n Logger.debug(\"[MetaUI CompactLayout]\", `Rendering scalar field '${bindingPath}'.`, \"CompactLayout\");\n this._renderScalarField(container, element, bindingPath, meta, modelName, engine);\n }\n } else {\n Logger.warn(`[MetaUI] Unsupported layout element type '${element.type}'.`, \"\", \"CompactLayout\");\n }\n };\n\n // Render everything defined in the layout\n schema.uiLayout.forEach(renderElement);\n\n // Render array/table sub-layouts full width below the fields\n tableElements.forEach(field => {\n try {\n const subSchema = {\n type: \"array\",\n title: field.label || field.meta.ui?.label || field.scope,\n items: field.meta.items || { type: \"object\", properties: {} },\n uiLayout: field.meta.items?.uiLayout\n };\n \n const control = engine.generateLayout(subSchema as ISchema, modelName, `/${field.scope}`);\n if (control) {\n control.addStyleClass(\"sapUiTinyMarginTop\");\n container.addItem(control);\n }\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI] Failed to render array field ${field.scope}`, msg, \"CompactLayout\");\n Logger.showErrorPopup(`Failed to render array field '${field.scope}'.\\n\\nDetails: ${msg}`);\n }\n });\n\n return container;\n }\n\n private _renderScalarField(container: VBox, element: ILayoutElement, propKey: string, meta: IPropertyMetadata, modelName: string, engine: Engine): void {\n try {\n const labelText = element.label || meta.ui?.label || propKey;\n const label = new Label({\n text: labelText,\n required: meta.required\n });\n label.addStyleClass(\"sapUiTinyMarginTop\");\n\n const effectiveMeta = { ...meta };\n if (element.widget) {\n effectiveMeta.ui = { ...meta.ui, widget: element.widget };\n }\n\n const control = engine.generateField(effectiveMeta, `/${propKey}`, modelName);\n control.addStyleClass(\"sapUiTinyMarginBottom\");\n\n // Wrap label and field tightly\n const fieldBox = new VBox({ renderType: \"Bare\", items: [label, control] });\n container.addItem(fieldBox);\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI] Failed to render field ${propKey}`, msg, \"CompactLayout\");\n Logger.showErrorPopup(`Failed to render field '${propKey}'.\\n\\nDetails: ${msg}`);\n }\n }\n}\n"],"mappings":";;;QAWSA,gBAAgB,GAAAC,wBAAA;EAAA,MAChBC,MAAM,GAAAC,eAAA;EAGf;AACA;AACA;AACA;AACA;AACA;AACA;EACO,MAAMC,aAAa,CAA2B;IACjD;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;IACWC,MAAMA,CAACC,MAAe,EAAEC,SAAiB,EAAEC,MAAc,EAAEC,QAAqB,EAAW;MAC9F,MAAMC,SAAS,GAAG,IAAIC,IAAI,CAAC;QAAEC,UAAU,EAAE;MAAO,CAAC,CAAC;MAClDF,SAAS,CAACG,aAAa,CAAC,iBAAiB,CAAC;MAE1C,IAAI,CAACP,MAAM,CAACQ,QAAQ,IAAI,CAACC,KAAK,CAACC,OAAO,CAACV,MAAM,CAACQ,QAAQ,CAAC,EAAE;QACrDZ,MAAM,CAACe,IAAI,CAAC,wFAAwF,CAAC;QACrG,OAAOP,SAAS;MACpB;MAEA,MAAMQ,aAA2E,GAAG,EAAE;;MAEtF;MACA,MAAMC,aAAa,GAAIC,OAAuB,IAAK;QAC/C,IAAIA,OAAO,CAACC,IAAI,KAAK,OAAO,EAAE;UAC1B,IAAID,OAAO,CAACE,KAAK,EAAE;YACf,MAAMC,KAAK,GAAG,IAAIC,GAAG,CAACC,CAAC,CAACC,KAAK,CAAC;cAAEC,IAAI,EAAEP,OAAO,CAACE,KAAK;cAAEM,KAAK,EAAE;YAAK,CAAC,CAAC;YACnEL,KAAK,CAACV,aAAa,CAAC,0CAA0C,CAAC;YAC/DH,SAAS,CAACmB,OAAO,CAACN,KAAK,CAAC;UAC5B;UAEA,IAAIH,OAAO,CAACU,QAAQ,IAAIf,KAAK,CAACC,OAAO,CAACI,OAAO,CAACU,QAAQ,CAAC,EAAE;YACrDV,OAAO,CAACU,QAAQ,CAACC,OAAO,CAACZ,aAAa,CAAC;UAC3C;QACJ,CAAC,MAAM,IAAIC,OAAO,CAACC,IAAI,KAAK,SAAS,EAAE;UACnC,IAAI,CAACD,OAAO,CAACY,KAAK,IAAI,CAACZ,OAAO,CAACY,KAAK,CAACC,UAAU,CAAC,eAAe,CAAC,EAAE;YAC9D/B,MAAM,CAACgC,KAAK,CAAC,2BAA2Bd,OAAO,CAACY,KAAK,wBAAwB,EAAE,EAAE,EAAE,eAAe,CAAC;YACnG;UACJ;UAEA,MAAM;YAAEG,IAAI;YAAEC,WAAW;YAAEC;UAAQ,CAAC,GAAGrC,gBAAgB,CAACsC,YAAY,CAAChC,MAAM,EAAEc,OAAO,CAACY,KAAK,CAAC;UAE3F,IAAI,CAACG,IAAI,EAAE;YACPjC,MAAM,CAACgC,KAAK,CAAC,sBAAsBG,OAAO,oCAAoC,EAAE,EAAE,EAAE,eAAe,CAAC;YACpG;UACJ;UAEA,MAAME,qBAAqB,GAAGJ,IAAI,CAACK,KAAK,EAAEnB,IAAI,KAAK,QAAQ,IAAIc,IAAI,CAACK,KAAK,EAAEC,UAAU;UACrF,MAAMC,iBAAiB,GAAG,CAAC,CAACP,IAAI,CAACQ,EAAE,EAAEC,MAAM;UAC3C,MAAMC,WAAW,GAAGV,IAAI,CAACd,IAAI,KAAK,OAAO,IAAIkB,qBAAqB,IAAI,CAACG,iBAAiB;UAExF,IAAIG,WAAW,EAAE;YACb3C,MAAM,CAAC4C,KAAK,CAAC,wBAAwB,EAAE,qBAAqBT,OAAO,wBAAwB,EAAE,eAAe,CAAC;YAC7GnB,aAAa,CAAC6B,IAAI,CAAC;cAAEf,KAAK,EAAEI,WAAW;cAAED,IAAI;cAAEb,KAAK,EAAEF,OAAO,CAACE;YAAM,CAAC,CAAC;UAC1E,CAAC,MAAM;YACHpB,MAAM,CAAC4C,KAAK,CAAC,wBAAwB,EAAE,2BAA2BV,WAAW,IAAI,EAAE,eAAe,CAAC;YACnG,IAAI,CAACY,kBAAkB,CAACtC,SAAS,EAAEU,OAAO,EAAEgB,WAAW,EAAED,IAAI,EAAE5B,SAAS,EAAEC,MAAM,CAAC;UACrF;QACJ,CAAC,MAAM;UACHN,MAAM,CAACe,IAAI,CAAC,6CAA6CG,OAAO,CAACC,IAAI,IAAI,EAAE,EAAE,EAAE,eAAe,CAAC;QACnG;MACJ,CAAC;;MAED;MACAf,MAAM,CAACQ,QAAQ,CAACiB,OAAO,CAACZ,aAAa,CAAC;;MAEtC;MACAD,aAAa,CAACa,OAAO,CAACkB,KAAK,IAAI;QAC3B,IAAI;UACA,MAAMC,SAAS,GAAG;YACd7B,IAAI,EAAE,OAAO;YACbE,KAAK,EAAE0B,KAAK,CAAC3B,KAAK,IAAI2B,KAAK,CAACd,IAAI,CAACQ,EAAE,EAAErB,KAAK,IAAI2B,KAAK,CAACjB,KAAK;YACzDQ,KAAK,EAAES,KAAK,CAACd,IAAI,CAACK,KAAK,IAAI;cAAEnB,IAAI,EAAE,QAAQ;cAAEoB,UAAU,EAAE,CAAC;YAAE,CAAC;YAC7D3B,QAAQ,EAAEmC,KAAK,CAACd,IAAI,CAACK,KAAK,EAAE1B;UAChC,CAAC;UAED,MAAMqC,OAAO,GAAG3C,MAAM,CAAC4C,cAAc,CAACF,SAAS,EAAa3C,SAAS,EAAE,IAAI0C,KAAK,CAACjB,KAAK,EAAE,CAAC;UACzF,IAAImB,OAAO,EAAE;YACTA,OAAO,CAACtC,aAAa,CAAC,oBAAoB,CAAC;YAC3CH,SAAS,CAACmB,OAAO,CAACsB,OAAO,CAAC;UAC9B;QACJ,CAAC,CAAC,OAAOjB,KAAK,EAAE;UACZ,MAAMmB,GAAG,GAAInB,KAAK,CAAWoB,OAAO;UACpCpD,MAAM,CAACgC,KAAK,CAAC,yCAAyCe,KAAK,CAACjB,KAAK,EAAE,EAAEqB,GAAG,EAAE,eAAe,CAAC;UAC1FnD,MAAM,CAACqD,cAAc,CAAC,iCAAiCN,KAAK,CAACjB,KAAK,kBAAkBqB,GAAG,EAAE,CAAC;QAC9F;MACJ,CAAC,CAAC;MAEF,OAAO3C,SAAS;IACpB;IAEQsC,kBAAkBA,CAACtC,SAAe,EAAEU,OAAuB,EAAEiB,OAAe,EAAEF,IAAuB,EAAE5B,SAAiB,EAAEC,MAAc,EAAQ;MACpJ,IAAI;QACA,MAAMgD,SAAS,GAAGpC,OAAO,CAACE,KAAK,IAAIa,IAAI,CAACQ,EAAE,EAAErB,KAAK,IAAIe,OAAO;QAC5D,MAAMf,KAAK,GAAG,IAAImC,KAAK,CAAC;UACpB9B,IAAI,EAAE6B,SAAS;UACfE,QAAQ,EAAEvB,IAAI,CAACuB;QACnB,CAAC,CAAC;QACFpC,KAAK,CAACT,aAAa,CAAC,oBAAoB,CAAC;QAEzC,MAAM8C,aAAa,GAAG;UAAE,GAAGxB;QAAK,CAAC;QACjC,IAAIf,OAAO,CAACwB,MAAM,EAAE;UAChBe,aAAa,CAAChB,EAAE,GAAG;YAAE,GAAGR,IAAI,CAACQ,EAAE;YAAEC,MAAM,EAAExB,OAAO,CAACwB;UAAO,CAAC;QAC7D;QAEA,MAAMO,OAAO,GAAG3C,MAAM,CAACoD,aAAa,CAACD,aAAa,EAAE,IAAItB,OAAO,EAAE,EAAE9B,SAAS,CAAC;QAC7E4C,OAAO,CAACtC,aAAa,CAAC,uBAAuB,CAAC;;QAE9C;QACA,MAAMgD,QAAQ,GAAG,IAAIlD,IAAI,CAAC;UAAEC,UAAU,EAAE,MAAM;UAAE4B,KAAK,EAAE,CAAClB,KAAK,EAAE6B,OAAO;QAAE,CAAC,CAAC;QAC1EzC,SAAS,CAACmB,OAAO,CAACgC,QAAQ,CAAC;MAC/B,CAAC,CAAC,OAAO3B,KAAK,EAAE;QACZ,MAAMmB,GAAG,GAAInB,KAAK,CAAWoB,OAAO;QACpCpD,MAAM,CAACgC,KAAK,CAAC,mCAAmCG,OAAO,EAAE,EAAEgB,GAAG,EAAE,eAAe,CAAC;QAChFnD,MAAM,CAACqD,cAAc,CAAC,2BAA2BlB,OAAO,kBAAkBgB,GAAG,EAAE,CAAC;MACpF;IACJ;EACJ;EAAC,IAAAS,SAAA;IAAAC,UAAA;EAAA;EAAAD,SAAA,CAAA1D,aAAA,GAAAA,aAAA;EAAA,OAAA0D,SAAA;AAAA","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"CompactLayout.d.ts","sourceRoot":"../../../../../../../..","sources":["src/nz/co/siliconst/ui5/metaui/layouts/CompactLayout.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,kDAAkD,CAAC;IASlE,OAAO,EAAqB,OAAO,EAAkB,MAAM,+CAA+C,CAAC;IAC3G,OAAO,EAAE,cAAc,EAAE,MAAM,sDAAsD,CAAC;IACtF,OAAO,EAAE,MAAM,EAAE,MAAM,wCAAwC,CAAC;IAEhE,OAAO,OAAO,MAAM,qBAAqB,CAAC;IAE1C;;;;;;OAMG;IACH,MAAa,aAAc,YAAW,cAAc;QAChD;;;;;;;;WAQG;QACI,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO;QAiFjG,OAAO,CAAC,kBAAkB;KA0B7B;CAEA"}
1
+ {"version":3,"file":"CompactLayout.d.ts","sourceRoot":"../../../../../../../..","sources":["src/nz/co/siliconst/ui5/metaui/layouts/CompactLayout.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,kDAAkD,CAAC;IASlE,OAAO,EAAqB,OAAO,EAAkB,MAAM,+CAA+C,CAAC;IAC3G,OAAO,EAAE,cAAc,EAAE,MAAM,sDAAsD,CAAC;IACtF,OAAO,EAAE,MAAM,EAAE,MAAM,wCAAwC,CAAC;IAGhE,OAAO,OAAO,MAAM,qBAAqB,CAAC;IAE1C;;;;;;OAMG;IACH,MAAa,aAAc,YAAW,cAAc;QAChD;;;;;;;;WAQG;QACI,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO;QAgFjG,OAAO,CAAC,kBAAkB;KA0B7B;CAEA"}
@@ -1,2 +1,2 @@
1
- sap.ui.define(["sap/m/VBox","sap/m/Label","../utils/Logger"],function(e,t,a){"use strict";const r=a["Logger"];class o{render(t,a,o,i){const s=new e({renderType:"Bare"});s.addStyleClass("sapUiTinyMargin");if(!t.uiLayout||!Array.isArray(t.uiLayout)){r.warn("[MetaUI] Missing 'uiLayout' array in schema. CompactLayout will not render any fields.");return s}const n=[];const l=e=>{if(e.type==="Group"){if(e.label){const t=new sap.m.Title({text:e.label,level:"H5"});t.addStyleClass("sapUiTinyMarginTop sapUiTinyMarginBottom");s.addItem(t)}if(e.elements&&Array.isArray(e.elements)){e.elements.forEach(l)}}else if(e.type==="Control"){if(!e.scope||!e.scope.startsWith("#/properties/")){r.error(`[MetaUI] Invalid scope '${e.scope}' in uiLayout Control.`,"","CompactLayout");return}const i=e.scope.replace("#/properties/","");const l=t.properties?.[i];if(!l){r.error(`[MetaUI] Property '${i}' not found in schema definitions.`,"","CompactLayout");return}const p=l.items?.type==="object"||l.items?.properties;const c=!!l.ui?.widget;const u=l.type==="array"&&p&&!c;if(u){r.debug("[MetaUI CompactLayout]",`Routing property '${i}' to Table Sub-Layout.`,"CompactLayout");n.push({scope:i,meta:l,label:e.label})}else{r.debug("[MetaUI CompactLayout]",`Rendering scalar field '${i}'.`,"CompactLayout");this._renderScalarField(s,e,i,l,a,o)}}else{r.warn(`[MetaUI] Unsupported layout element type '${e.type}'.`,"","CompactLayout")}};t.uiLayout.forEach(l);n.forEach(e=>{try{const t={type:"array",title:e.label||e.meta.ui?.label||e.scope,items:e.meta.items||{type:"object",properties:{}},uiLayout:e.meta.items?.uiLayout};const r=o.generateLayout(t,a,`/${e.scope}`);if(r){r.addStyleClass("sapUiTinyMarginTop");s.addItem(r)}}catch(t){const a=t.message;r.error(`[MetaUI] Failed to render array field ${e.scope}`,a,"CompactLayout");r.showErrorPopup(`Failed to render array field '${e.scope}'.\n\nDetails: ${a}`)}});return s}_renderScalarField(a,o,i,s,n,l){try{const r=o.label||s.ui?.label||i;const p=new t({text:r,required:s.required});p.addStyleClass("sapUiTinyMarginTop");const c={...s};if(o.widget){c.ui={...s.ui,widget:o.widget}}const u=l.generateField(c,`/${i}`,n);u.addStyleClass("sapUiTinyMarginBottom");const y=new e({renderType:"Bare",items:[p,u]});a.addItem(y)}catch(e){const t=e.message;r.error(`[MetaUI] Failed to render field ${i}`,t,"CompactLayout");r.showErrorPopup(`Failed to render field '${i}'.\n\nDetails: ${t}`)}}}var i={__esModule:true};i.CompactLayout=o;return i});
1
+ sap.ui.define(["sap/m/VBox","sap/m/Label","../core/SchemaNormalizer","../utils/Logger"],function(e,t,a,r){"use strict";const o=a["SchemaNormalizer"];const i=r["Logger"];class s{render(t,a,r,s){const n=new e({renderType:"Bare"});n.addStyleClass("sapUiTinyMargin");if(!t.uiLayout||!Array.isArray(t.uiLayout)){i.warn("[MetaUI] Missing 'uiLayout' array in schema. CompactLayout will not render any fields.");return n}const l=[];const p=e=>{if(e.type==="Group"){if(e.label){const t=new sap.m.Title({text:e.label,level:"H5"});t.addStyleClass("sapUiTinyMarginTop sapUiTinyMarginBottom");n.addItem(t)}if(e.elements&&Array.isArray(e.elements)){e.elements.forEach(p)}}else if(e.type==="Control"){if(!e.scope||!e.scope.startsWith("#/properties/")){i.error(`[MetaUI] Invalid scope '${e.scope}' in uiLayout Control.`,"","CompactLayout");return}const{meta:s,bindingPath:p,propKey:c}=o.resolveScope(t,e.scope);if(!s){i.error(`[MetaUI] Property '${c}' not found in schema definitions.`,"","CompactLayout");return}const y=s.items?.type==="object"||s.items?.properties;const u=!!s.ui?.widget;const d=s.type==="array"&&y&&!u;if(d){i.debug("[MetaUI CompactLayout]",`Routing property '${c}' to Table Sub-Layout.`,"CompactLayout");l.push({scope:p,meta:s,label:e.label})}else{i.debug("[MetaUI CompactLayout]",`Rendering scalar field '${p}'.`,"CompactLayout");this._renderScalarField(n,e,p,s,a,r)}}else{i.warn(`[MetaUI] Unsupported layout element type '${e.type}'.`,"","CompactLayout")}};t.uiLayout.forEach(p);l.forEach(e=>{try{const t={type:"array",title:e.label||e.meta.ui?.label||e.scope,items:e.meta.items||{type:"object",properties:{}},uiLayout:e.meta.items?.uiLayout};const o=r.generateLayout(t,a,`/${e.scope}`);if(o){o.addStyleClass("sapUiTinyMarginTop");n.addItem(o)}}catch(t){const a=t.message;i.error(`[MetaUI] Failed to render array field ${e.scope}`,a,"CompactLayout");i.showErrorPopup(`Failed to render array field '${e.scope}'.\n\nDetails: ${a}`)}});return n}_renderScalarField(a,r,o,s,n,l){try{const i=r.label||s.ui?.label||o;const p=new t({text:i,required:s.required});p.addStyleClass("sapUiTinyMarginTop");const c={...s};if(r.widget){c.ui={...s.ui,widget:r.widget}}const y=l.generateField(c,`/${o}`,n);y.addStyleClass("sapUiTinyMarginBottom");const u=new e({renderType:"Bare",items:[p,y]});a.addItem(u)}catch(e){const t=e.message;i.error(`[MetaUI] Failed to render field ${o}`,t,"CompactLayout");i.showErrorPopup(`Failed to render field '${o}'.\n\nDetails: ${t}`)}}}var n={__esModule:true};n.CompactLayout=s;return n});
2
2
  //# sourceMappingURL=CompactLayout.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CompactLayout.js","names":["Logger","___utils_Logger","CompactLayout","render","schema","modelName","engine","onSubmit","container","VBox","renderType","addStyleClass","uiLayout","Array","isArray","warn","tableElements","renderElement","element","type","label","title","sap","m","Title","text","level","addItem","elements","forEach","scope","startsWith","error","propKey","replace","meta","properties","isCollectionOfRecords","items","hasExplicitWidget","ui","widget","isSubLayout","debug","push","this","_renderScalarField","field","subSchema","control","generateLayout","msg","message","showErrorPopup","labelText","Label","required","effectiveMeta","generateField","fieldBox","__exports","__esModule"],"sources":["CompactLayout.ts"],"sourcesContent":["/**\n * @file CompactLayout.ts\n * @description Generates a lightweight, dense VBox layout for use inside tight spaces like table cells.\n */\n\nimport VBox from \"sap/m/VBox\";\nimport Label from \"sap/m/Label\";\nimport Title from \"sap/ui/core/Title\";\nimport { IPropertyMetadata, ISchema, ILayoutElement } from \"../interfaces/ISchema\";\nimport { ILayoutManager } from \"../interfaces/ILayoutManager\";\nimport { Engine } from \"../core/Engine\";\nimport { Logger } from \"../utils/Logger\";\nimport Control from \"sap/ui/core/Control\";\n\n/**\n * Layout Manager responsible for generating a dense, lightweight layout (no SimpleForm padding).\n * Ideal for rendering objects dynamically inside table cells or side-panels.\n * \n * @namespace nz.co.siliconst.ui5.metaui.layouts\n * @public\n */\nexport class CompactLayout implements ILayoutManager {\n /**\n * Renders the JSON Schema properties into a dense VBox layout.\n * \n * @param schema The active JSON schema subset.\n * @param modelName The bound UI5 model name.\n * @param engine The central orchestrator for delegating plugin generation.\n * @param onSubmit Optional submit hook.\n * @returns {Control} The VBox wrapper containing the generated compact form.\n */\n public render(schema: ISchema, modelName: string, engine: Engine, onSubmit?: () => void): Control {\n const container = new VBox({ renderType: \"Bare\" });\n container.addStyleClass(\"sapUiTinyMargin\");\n\n if (!schema.uiLayout || !Array.isArray(schema.uiLayout)) {\n Logger.warn(\"[MetaUI] Missing 'uiLayout' array in schema. CompactLayout will not render any fields.\");\n return container;\n }\n\n const tableElements: { scope: string, meta: IPropertyMetadata, label?: string }[] = [];\n\n // Recursively render layout elements\n const renderElement = (element: ILayoutElement) => {\n if (element.type === \"Group\") {\n if (element.label) {\n const title = new sap.m.Title({ text: element.label, level: \"H5\" });\n title.addStyleClass(\"sapUiTinyMarginTop sapUiTinyMarginBottom\");\n container.addItem(title);\n }\n \n if (element.elements && Array.isArray(element.elements)) {\n element.elements.forEach(renderElement);\n }\n } else if (element.type === \"Control\") {\n if (!element.scope || !element.scope.startsWith(\"#/properties/\")) {\n Logger.error(`[MetaUI] Invalid scope '${element.scope}' in uiLayout Control.`, \"\", \"CompactLayout\");\n return;\n }\n \n const propKey = element.scope.replace(\"#/properties/\", \"\");\n const meta = schema.properties?.[propKey];\n \n if (!meta) {\n Logger.error(`[MetaUI] Property '${propKey}' not found in schema definitions.`, \"\", \"CompactLayout\");\n return;\n }\n\n const isCollectionOfRecords = meta.items?.type === \"object\" || meta.items?.properties;\n const hasExplicitWidget = !!meta.ui?.widget;\n const isSubLayout = meta.type === \"array\" && isCollectionOfRecords && !hasExplicitWidget;\n\n if (isSubLayout) {\n Logger.debug(\"[MetaUI CompactLayout]\", `Routing property '${propKey}' to Table Sub-Layout.`, \"CompactLayout\");\n tableElements.push({ scope: propKey, meta, label: element.label });\n } else {\n Logger.debug(\"[MetaUI CompactLayout]\", `Rendering scalar field '${propKey}'.`, \"CompactLayout\");\n this._renderScalarField(container, element, propKey, meta, modelName, engine);\n }\n } else {\n Logger.warn(`[MetaUI] Unsupported layout element type '${element.type}'.`, \"\", \"CompactLayout\");\n }\n };\n\n // Render everything defined in the layout\n schema.uiLayout.forEach(renderElement);\n\n // Render array/table sub-layouts full width below the fields\n tableElements.forEach(field => {\n try {\n const subSchema = {\n type: \"array\",\n title: field.label || field.meta.ui?.label || field.scope,\n items: field.meta.items || { type: \"object\", properties: {} },\n uiLayout: field.meta.items?.uiLayout\n };\n \n const control = engine.generateLayout(subSchema as ISchema, modelName, `/${field.scope}`);\n if (control) {\n control.addStyleClass(\"sapUiTinyMarginTop\");\n container.addItem(control);\n }\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI] Failed to render array field ${field.scope}`, msg, \"CompactLayout\");\n Logger.showErrorPopup(`Failed to render array field '${field.scope}'.\\n\\nDetails: ${msg}`);\n }\n });\n\n return container;\n }\n\n private _renderScalarField(container: VBox, element: ILayoutElement, propKey: string, meta: IPropertyMetadata, modelName: string, engine: Engine): void {\n try {\n const labelText = element.label || meta.ui?.label || propKey;\n const label = new Label({\n text: labelText,\n required: meta.required\n });\n label.addStyleClass(\"sapUiTinyMarginTop\");\n\n const effectiveMeta = { ...meta };\n if (element.widget) {\n effectiveMeta.ui = { ...meta.ui, widget: element.widget };\n }\n\n const control = engine.generateField(effectiveMeta, `/${propKey}`, modelName);\n control.addStyleClass(\"sapUiTinyMarginBottom\");\n\n // Wrap label and field tightly\n const fieldBox = new VBox({ renderType: \"Bare\", items: [label, control] });\n container.addItem(fieldBox);\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI] Failed to render field ${propKey}`, msg, \"CompactLayout\");\n Logger.showErrorPopup(`Failed to render field '${propKey}'.\\n\\nDetails: ${msg}`);\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"CompactLayout.js","names":["SchemaNormalizer","___core_SchemaNormalizer","Logger","___utils_Logger","CompactLayout","render","schema","modelName","engine","onSubmit","container","VBox","renderType","addStyleClass","uiLayout","Array","isArray","warn","tableElements","renderElement","element","type","label","title","sap","m","Title","text","level","addItem","elements","forEach","scope","startsWith","error","meta","bindingPath","propKey","resolveScope","isCollectionOfRecords","items","properties","hasExplicitWidget","ui","widget","isSubLayout","debug","push","this","_renderScalarField","field","subSchema","control","generateLayout","msg","message","showErrorPopup","labelText","Label","required","effectiveMeta","generateField","fieldBox","__exports","__esModule"],"sources":["CompactLayout.ts"],"sourcesContent":["/**\n * @file CompactLayout.ts\n * @description Generates a lightweight, dense VBox layout for use inside tight spaces like table cells.\n */\n\nimport VBox from \"sap/m/VBox\";\nimport Label from \"sap/m/Label\";\nimport Title from \"sap/ui/core/Title\";\nimport { IPropertyMetadata, ISchema, ILayoutElement } from \"../interfaces/ISchema\";\nimport { ILayoutManager } from \"../interfaces/ILayoutManager\";\nimport { Engine } from \"../core/Engine\";\nimport { SchemaNormalizer } from \"../core/SchemaNormalizer\";\nimport { Logger } from \"../utils/Logger\";\nimport Control from \"sap/ui/core/Control\";\n\n/**\n * Layout Manager responsible for generating a dense, lightweight layout (no SimpleForm padding).\n * Ideal for rendering objects dynamically inside table cells or side-panels.\n * \n * @namespace nz.co.siliconst.ui5.metaui.layouts\n * @public\n */\nexport class CompactLayout implements ILayoutManager {\n /**\n * Renders the JSON Schema properties into a dense VBox layout.\n * \n * @param schema The active JSON schema subset.\n * @param modelName The bound UI5 model name.\n * @param engine The central orchestrator for delegating plugin generation.\n * @param onSubmit Optional submit hook.\n * @returns {Control} The VBox wrapper containing the generated compact form.\n */\n public render(schema: ISchema, modelName: string, engine: Engine, onSubmit?: () => void): Control {\n const container = new VBox({ renderType: \"Bare\" });\n container.addStyleClass(\"sapUiTinyMargin\");\n\n if (!schema.uiLayout || !Array.isArray(schema.uiLayout)) {\n Logger.warn(\"[MetaUI] Missing 'uiLayout' array in schema. CompactLayout will not render any fields.\");\n return container;\n }\n\n const tableElements: { scope: string, meta: IPropertyMetadata, label?: string }[] = [];\n\n // Recursively render layout elements\n const renderElement = (element: ILayoutElement) => {\n if (element.type === \"Group\") {\n if (element.label) {\n const title = new sap.m.Title({ text: element.label, level: \"H5\" });\n title.addStyleClass(\"sapUiTinyMarginTop sapUiTinyMarginBottom\");\n container.addItem(title);\n }\n \n if (element.elements && Array.isArray(element.elements)) {\n element.elements.forEach(renderElement);\n }\n } else if (element.type === \"Control\") {\n if (!element.scope || !element.scope.startsWith(\"#/properties/\")) {\n Logger.error(`[MetaUI] Invalid scope '${element.scope}' in uiLayout Control.`, \"\", \"CompactLayout\");\n return;\n }\n \n const { meta, bindingPath, propKey } = SchemaNormalizer.resolveScope(schema, element.scope);\n \n if (!meta) {\n Logger.error(`[MetaUI] Property '${propKey}' not found in schema definitions.`, \"\", \"CompactLayout\");\n return;\n }\n\n const isCollectionOfRecords = meta.items?.type === \"object\" || meta.items?.properties;\n const hasExplicitWidget = !!meta.ui?.widget;\n const isSubLayout = meta.type === \"array\" && isCollectionOfRecords && !hasExplicitWidget;\n\n if (isSubLayout) {\n Logger.debug(\"[MetaUI CompactLayout]\", `Routing property '${propKey}' to Table Sub-Layout.`, \"CompactLayout\");\n tableElements.push({ scope: bindingPath, meta, label: element.label });\n } else {\n Logger.debug(\"[MetaUI CompactLayout]\", `Rendering scalar field '${bindingPath}'.`, \"CompactLayout\");\n this._renderScalarField(container, element, bindingPath, meta, modelName, engine);\n }\n } else {\n Logger.warn(`[MetaUI] Unsupported layout element type '${element.type}'.`, \"\", \"CompactLayout\");\n }\n };\n\n // Render everything defined in the layout\n schema.uiLayout.forEach(renderElement);\n\n // Render array/table sub-layouts full width below the fields\n tableElements.forEach(field => {\n try {\n const subSchema = {\n type: \"array\",\n title: field.label || field.meta.ui?.label || field.scope,\n items: field.meta.items || { type: \"object\", properties: {} },\n uiLayout: field.meta.items?.uiLayout\n };\n \n const control = engine.generateLayout(subSchema as ISchema, modelName, `/${field.scope}`);\n if (control) {\n control.addStyleClass(\"sapUiTinyMarginTop\");\n container.addItem(control);\n }\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI] Failed to render array field ${field.scope}`, msg, \"CompactLayout\");\n Logger.showErrorPopup(`Failed to render array field '${field.scope}'.\\n\\nDetails: ${msg}`);\n }\n });\n\n return container;\n }\n\n private _renderScalarField(container: VBox, element: ILayoutElement, propKey: string, meta: IPropertyMetadata, modelName: string, engine: Engine): void {\n try {\n const labelText = element.label || meta.ui?.label || propKey;\n const label = new Label({\n text: labelText,\n required: meta.required\n });\n label.addStyleClass(\"sapUiTinyMarginTop\");\n\n const effectiveMeta = { ...meta };\n if (element.widget) {\n effectiveMeta.ui = { ...meta.ui, widget: element.widget };\n }\n\n const control = engine.generateField(effectiveMeta, `/${propKey}`, modelName);\n control.addStyleClass(\"sapUiTinyMarginBottom\");\n\n // Wrap label and field tightly\n const fieldBox = new VBox({ renderType: \"Bare\", items: [label, control] });\n container.addItem(fieldBox);\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI] Failed to render field ${propKey}`, msg, \"CompactLayout\");\n Logger.showErrorPopup(`Failed to render field '${propKey}'.\\n\\nDetails: ${msg}`);\n }\n }\n}\n"],"mappings":"6HAWSA,EAAgBC,EAAA,0BAChBC,EAAMC,EAAA,UAUR,MAAMC,EAUFC,OAAOC,EAAiBC,EAAmBC,EAAgBC,GAC9D,MAAMC,EAAY,IAAIC,EAAK,CAAEC,WAAY,SACzCF,EAAUG,cAAc,mBAExB,IAAKP,EAAOQ,WAAaC,MAAMC,QAAQV,EAAOQ,UAAW,CACrDZ,EAAOe,KAAK,0FACZ,OAAOP,CACX,CAEA,MAAMQ,EAA8E,GAGpF,MAAMC,EAAiBC,IACnB,GAAIA,EAAQC,OAAS,QAAS,CAC1B,GAAID,EAAQE,MAAO,CACf,MAAMC,EAAQ,IAAIC,IAAIC,EAAEC,MAAM,CAAEC,KAAMP,EAAQE,MAAOM,MAAO,OAC5DL,EAAMV,cAAc,4CACpBH,EAAUmB,QAAQN,EACtB,CAEA,GAAIH,EAAQU,UAAYf,MAAMC,QAAQI,EAAQU,UAAW,CACrDV,EAAQU,SAASC,QAAQZ,EAC7B,CACJ,MAAO,GAAIC,EAAQC,OAAS,UAAW,CACnC,IAAKD,EAAQY,QAAUZ,EAAQY,MAAMC,WAAW,iBAAkB,CAC9D/B,EAAOgC,MAAM,2BAA2Bd,EAAQY,8BAA+B,GAAI,iBACnF,MACJ,CAEA,MAAMG,KAAEA,EAAIC,YAAEA,EAAWC,QAAEA,GAAYrC,EAAiBsC,aAAahC,EAAQc,EAAQY,OAErF,IAAKG,EAAM,CACPjC,EAAOgC,MAAM,sBAAsBG,sCAA6C,GAAI,iBACpF,MACJ,CAEA,MAAME,EAAwBJ,EAAKK,OAAOnB,OAAS,UAAYc,EAAKK,OAAOC,WAC3E,MAAMC,IAAsBP,EAAKQ,IAAIC,OACrC,MAAMC,EAAcV,EAAKd,OAAS,SAAWkB,IAA0BG,EAEvE,GAAIG,EAAa,CACb3C,EAAO4C,MAAM,yBAA0B,qBAAqBT,0BAAiC,iBAC7FnB,EAAc6B,KAAK,CAAEf,MAAOI,EAAaD,OAAMb,MAAOF,EAAQE,OAClE,KAAO,CACHpB,EAAO4C,MAAM,yBAA0B,2BAA2BV,MAAiB,iBACnFY,KAAKC,mBAAmBvC,EAAWU,EAASgB,EAAaD,EAAM5B,EAAWC,EAC9E,CACJ,KAAO,CACHN,EAAOe,KAAK,6CAA6CG,EAAQC,SAAU,GAAI,gBACnF,GAIJf,EAAOQ,SAASiB,QAAQZ,GAGxBD,EAAca,QAAQmB,IAClB,IACI,MAAMC,EAAY,CACd9B,KAAM,QACNE,MAAO2B,EAAM5B,OAAS4B,EAAMf,KAAKQ,IAAIrB,OAAS4B,EAAMlB,MACpDQ,MAAOU,EAAMf,KAAKK,OAAS,CAAEnB,KAAM,SAAUoB,WAAY,CAAC,GAC1D3B,SAAUoC,EAAMf,KAAKK,OAAO1B,UAGhC,MAAMsC,EAAU5C,EAAO6C,eAAeF,EAAsB5C,EAAW,IAAI2C,EAAMlB,SACjF,GAAIoB,EAAS,CACTA,EAAQvC,cAAc,sBACtBH,EAAUmB,QAAQuB,EACtB,CACJ,CAAE,MAAOlB,GACL,MAAMoB,EAAOpB,EAAgBqB,QAC7BrD,EAAOgC,MAAM,yCAAyCgB,EAAMlB,QAASsB,EAAK,iBAC1EpD,EAAOsD,eAAe,iCAAiCN,EAAMlB,uBAAuBsB,IACxF,IAGJ,OAAO5C,CACX,CAEQuC,mBAAmBvC,EAAiBU,EAAyBiB,EAAiBF,EAAyB5B,EAAmBC,GAC9H,IACI,MAAMiD,EAAYrC,EAAQE,OAASa,EAAKQ,IAAIrB,OAASe,EACrD,MAAMf,EAAQ,IAAIoC,EAAM,CACpB/B,KAAM8B,EACNE,SAAUxB,EAAKwB,WAEnBrC,EAAMT,cAAc,sBAEpB,MAAM+C,EAAgB,IAAKzB,GAC3B,GAAIf,EAAQwB,OAAQ,CAChBgB,EAAcjB,GAAK,IAAKR,EAAKQ,GAAIC,OAAQxB,EAAQwB,OACrD,CAEA,MAAMQ,EAAU5C,EAAOqD,cAAcD,EAAe,IAAIvB,IAAW9B,GACnE6C,EAAQvC,cAAc,yBAGtB,MAAMiD,EAAW,IAAInD,EAAK,CAAEC,WAAY,OAAQ4B,MAAO,CAAClB,EAAO8B,KAC/D1C,EAAUmB,QAAQiC,EACtB,CAAE,MAAO5B,GACL,MAAMoB,EAAOpB,EAAgBqB,QAC7BrD,EAAOgC,MAAM,mCAAmCG,IAAWiB,EAAK,iBAChEpD,EAAOsD,eAAe,2BAA2BnB,mBAAyBiB,IAC9E,CACJ,EACH,IAAAS,EAAA,CAAAC,WAAA,MAAAD,EAAA3D,gBAAA,OAAA2D,CAAA","ignoreList":[]}
@@ -9,6 +9,7 @@ import Title from "sap/ui/core/Title";
9
9
  import { IPropertyMetadata, ISchema, ILayoutElement } from "../interfaces/ISchema";
10
10
  import { ILayoutManager } from "../interfaces/ILayoutManager";
11
11
  import { Engine } from "../core/Engine";
12
+ import { SchemaNormalizer } from "../core/SchemaNormalizer";
12
13
  import { Logger } from "../utils/Logger";
13
14
  import Control from "sap/ui/core/Control";
14
15
 
@@ -58,8 +59,7 @@ export class CompactLayout implements ILayoutManager {
58
59
  return;
59
60
  }
60
61
 
61
- const propKey = element.scope.replace("#/properties/", "");
62
- const meta = schema.properties?.[propKey];
62
+ const { meta, bindingPath, propKey } = SchemaNormalizer.resolveScope(schema, element.scope);
63
63
 
64
64
  if (!meta) {
65
65
  Logger.error(`[MetaUI] Property '${propKey}' not found in schema definitions.`, "", "CompactLayout");
@@ -72,10 +72,10 @@ export class CompactLayout implements ILayoutManager {
72
72
 
73
73
  if (isSubLayout) {
74
74
  Logger.debug("[MetaUI CompactLayout]", `Routing property '${propKey}' to Table Sub-Layout.`, "CompactLayout");
75
- tableElements.push({ scope: propKey, meta, label: element.label });
75
+ tableElements.push({ scope: bindingPath, meta, label: element.label });
76
76
  } else {
77
- Logger.debug("[MetaUI CompactLayout]", `Rendering scalar field '${propKey}'.`, "CompactLayout");
78
- this._renderScalarField(container, element, propKey, meta, modelName, engine);
77
+ Logger.debug("[MetaUI CompactLayout]", `Rendering scalar field '${bindingPath}'.`, "CompactLayout");
78
+ this._renderScalarField(container, element, bindingPath, meta, modelName, engine);
79
79
  }
80
80
  } else {
81
81
  Logger.warn(`[MetaUI] Unsupported layout element type '${element.type}'.`, "", "CompactLayout");
@@ -1,6 +1,7 @@
1
- sap.ui.define(["sap/ui/layout/form/SimpleForm", "sap/m/Label", "sap/ui/core/Title", "sap/m/VBox", "../utils/Logger"], function (SimpleForm, Label, Title, VBox, ___utils_Logger) {
1
+ sap.ui.define(["sap/ui/layout/form/SimpleForm", "sap/m/Label", "sap/ui/core/Title", "sap/m/VBox", "../core/SchemaNormalizer", "../utils/Logger"], function (SimpleForm, Label, Title, VBox, ___core_SchemaNormalizer, ___utils_Logger) {
2
2
  "use strict";
3
3
 
4
+ const SchemaNormalizer = ___core_SchemaNormalizer["SchemaNormalizer"];
4
5
  const Logger = ___utils_Logger["Logger"];
5
6
  /**
6
7
  * Layout Manager responsible for generating a fully responsive SAP Fiori SimpleForm.
@@ -65,8 +66,11 @@ sap.ui.define(["sap/ui/layout/form/SimpleForm", "sap/m/Label", "sap/ui/core/Titl
65
66
  Logger.error(`[MetaUI] Invalid scope '${element.scope}' in uiLayout Control.`, "", "FormLayout");
66
67
  return;
67
68
  }
68
- const propKey = element.scope.replace("#/properties/", "");
69
- const meta = schema.properties?.[propKey];
69
+ const {
70
+ meta,
71
+ bindingPath,
72
+ propKey
73
+ } = SchemaNormalizer.resolveScope(schema, element.scope);
70
74
  if (!meta) {
71
75
  Logger.error(`[MetaUI] Property '${propKey}' not found in schema definitions.`, "", "FormLayout");
72
76
  return;
@@ -81,14 +85,14 @@ sap.ui.define(["sap/ui/layout/form/SimpleForm", "sap/m/Label", "sap/ui/core/Titl
81
85
  if (isSubLayout) {
82
86
  Logger.debug("[MetaUI FormLayout]", `Routing property '${propKey}' to Table Sub-Layout.`, "FormLayout");
83
87
  tableElements.push({
84
- scope: propKey,
88
+ scope: bindingPath,
85
89
  meta,
86
90
  label: element.label
87
91
  });
88
92
  } else {
89
93
  hasFormFields = true;
90
- Logger.debug("[MetaUI FormLayout]", `Rendering scalar field '${propKey}'.`, "FormLayout");
91
- this._renderScalarField(form, element, propKey, meta, modelName, engine);
94
+ Logger.debug("[MetaUI FormLayout]", `Rendering scalar field '${bindingPath}'.`, "FormLayout");
95
+ this._renderScalarField(form, element, bindingPath, meta, modelName, engine);
92
96
  }
93
97
  } else {
94
98
  Logger.warn(`[MetaUI] Unsupported layout element type '${element.type}'.`, "", "FormLayout");
@@ -1 +1 @@
1
- {"version":3,"file":"FormLayout-dbg.js","names":["Logger","___utils_Logger","FormLayout","render","schema","modelName","engine","onSubmit","container","VBox","renderType","form","SimpleForm","editable","title","layout","labelSpanXL","labelSpanL","labelSpanM","labelSpanS","adjustLabelSpan","emptySpanXL","emptySpanL","emptySpanM","emptySpanS","columnsXL","columnsL","columnsM","singleContainerFullSize","uiLayout","Array","isArray","warn","addItem","tableElements","hasFormFields","renderElement","element","type","label","addContent","Title","text","elements","forEach","scope","startsWith","error","propKey","replace","meta","properties","isCollectionOfRecords","items","hasExplicitWidget","ui","widget","isSubLayout","debug","push","_renderScalarField","field","subSchema","control","generateLayout","addStyleClass","msg","message","showErrorPopup","labelText","Label","required","effectiveMeta","generateField","fullWidth","sap","require","GridData","setLayoutData","span","__exports","__esModule"],"sources":["FormLayout.ts"],"sourcesContent":["/**\n * @file FormLayout.ts\n * @description Generates a fully responsive SAP Fiori Form layout (SimpleForm).\n */\n\nimport SimpleForm from \"sap/ui/layout/form/SimpleForm\";\nimport Label from \"sap/m/Label\";\nimport Title from \"sap/ui/core/Title\";\nimport VBox from \"sap/m/VBox\";\nimport { IPropertyMetadata, ISchema, ILayoutElement } from \"../interfaces/ISchema\";\nimport { ILayoutManager } from \"../interfaces/ILayoutManager\";\nimport { Engine } from \"../core/Engine\";\nimport { Logger } from \"../utils/Logger\";\nimport Control from \"sap/ui/core/Control\";\n\n/**\n * Layout Manager responsible for generating a fully responsive SAP Fiori SimpleForm.\n * It traverses the `uiLayout` tree defined in the schema to build the form groups and fields,\n * completely separating visual orchestration from data modeling.\n * @namespace nz.co.siliconst.ui5.metaui.layouts\n * @public\n */\nexport class FormLayout implements ILayoutManager {\n /**\n * Renders the JSON Schema properties into a UI5 SimpleForm using the uiLayout definitions.\n * \n * @param schema The active JSON schema subset.\n * @param modelName The bound UI5 model name.\n * @param engine The central orchestrator for delegating plugin generation.\n * @param onSubmit Optional submit hook.\n * @returns {Control} The VBox wrapper containing the generated form.\n */\n public render(schema: ISchema, modelName: string, engine: Engine, onSubmit?: () => void): Control {\n const container = new VBox({ renderType: \"Bare\" });\n const form = new SimpleForm({\n editable: true,\n title: schema.title,\n layout: \"ResponsiveGridLayout\",\n labelSpanXL: 4, labelSpanL: 4, labelSpanM: 4, labelSpanS: 12,\n adjustLabelSpan: false,\n emptySpanXL: 0, emptySpanL: 0, emptySpanM: 0, emptySpanS: 0,\n columnsXL: 1, columnsL: 1, columnsM: 1,\n singleContainerFullSize: false\n });\n\n if (!schema.uiLayout || !Array.isArray(schema.uiLayout)) {\n Logger.warn(\"[MetaUI] Missing 'uiLayout' array in schema. Form will not render any fields.\");\n container.addItem(form);\n return container;\n }\n\n const tableElements: { scope: string, meta: IPropertyMetadata, label?: string }[] = [];\n let hasFormFields = false;\n\n // Recursively render layout elements\n const renderElement = (element: ILayoutElement) => {\n if (element.type === \"Group\") {\n if (element.label) {\n form.addContent(new Title({ text: element.label }));\n }\n \n if (element.elements && Array.isArray(element.elements)) {\n element.elements.forEach(renderElement);\n }\n } else if (element.type === \"Control\") {\n if (!element.scope || !element.scope.startsWith(\"#/properties/\")) {\n Logger.error(`[MetaUI] Invalid scope '${element.scope}' in uiLayout Control.`, \"\", \"FormLayout\");\n return;\n }\n \n const propKey = element.scope.replace(\"#/properties/\", \"\");\n const meta = schema.properties?.[propKey];\n \n if (!meta) {\n Logger.error(`[MetaUI] Property '${propKey}' not found in schema definitions.`, \"\", \"FormLayout\");\n return;\n }\n\n // Architectural Boundary: Separate Field Controls (Plugins) from Sub-Layouts (LayoutManagers)\n // A property is delegated to a Sub-Layout Manager (Table) ONLY if it represents a collection of complex objects.\n // Collections of primitives, or explicitly assigned widgets (like multiSelect), remain in the Form as Field Plugins.\n const isCollectionOfRecords = meta.items?.type === \"object\" || meta.items?.properties;\n const hasExplicitWidget = !!meta.ui?.widget;\n const isSubLayout = meta.type === \"array\" && isCollectionOfRecords && !hasExplicitWidget;\n\n if (isSubLayout) {\n Logger.debug(\"[MetaUI FormLayout]\", `Routing property '${propKey}' to Table Sub-Layout.`, \"FormLayout\");\n tableElements.push({ scope: propKey, meta, label: element.label });\n } else {\n hasFormFields = true;\n Logger.debug(\"[MetaUI FormLayout]\", `Rendering scalar field '${propKey}'.`, \"FormLayout\");\n this._renderScalarField(form, element, propKey, meta, modelName, engine);\n }\n } else {\n Logger.warn(`[MetaUI] Unsupported layout element type '${element.type}'.`, \"\", \"FormLayout\");\n }\n };\n\n // Render everything defined in the layout\n schema.uiLayout.forEach(renderElement);\n\n if (hasFormFields) {\n container.addItem(form);\n }\n\n // Render array/table sub-layouts full width below the form\n tableElements.forEach(field => {\n try {\n const subSchema = {\n type: \"array\",\n title: field.label || field.meta.ui?.label || field.scope,\n items: field.meta.items || { type: \"object\", properties: {} },\n uiLayout: field.meta.items?.uiLayout // Pass down sub-layout if available\n };\n \n const control = engine.generateLayout(subSchema as ISchema, modelName, `/${field.scope}`);\n if (control) {\n control.addStyleClass(\"sapUiSmallMarginTop\");\n container.addItem(control);\n }\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI] Failed to render array field ${field.scope}`, msg, \"FormLayout\");\n Logger.showErrorPopup(`Failed to render array field '${field.scope}'.\\n\\nDetails: ${msg}`);\n }\n });\n\n return container;\n }\n\n private _renderScalarField(form: SimpleForm, element: ILayoutElement, propKey: string, meta: IPropertyMetadata, modelName: string, engine: Engine): void {\n try {\n const labelText = element.label || meta.ui?.label || propKey;\n const label = new Label({\n text: labelText,\n required: meta.required\n });\n\n // Override widget if specified in the layout element\n const effectiveMeta = { ...meta };\n if (element.widget) {\n effectiveMeta.ui = { ...meta.ui, widget: element.widget };\n }\n\n const control = engine.generateField(effectiveMeta, `/${propKey}`, modelName);\n\n if (effectiveMeta.ui?.fullWidth) {\n sap.ui.require([\"sap/ui/layout/GridData\"], (GridData: any) => {\n control.setLayoutData(new GridData({ span: \"XL12 L12 M12 S12\" }));\n });\n }\n\n form.addContent(label);\n form.addContent(control);\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI] Failed to render field ${propKey}`, msg, \"FormLayout\");\n Logger.showErrorPopup(`Failed to render field '${propKey}'.\\n\\nDetails: ${msg}`);\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"FormLayout-dbg.js","names":["SchemaNormalizer","___core_SchemaNormalizer","Logger","___utils_Logger","FormLayout","render","schema","modelName","engine","onSubmit","container","VBox","renderType","form","SimpleForm","editable","title","layout","labelSpanXL","labelSpanL","labelSpanM","labelSpanS","adjustLabelSpan","emptySpanXL","emptySpanL","emptySpanM","emptySpanS","columnsXL","columnsL","columnsM","singleContainerFullSize","uiLayout","Array","isArray","warn","addItem","tableElements","hasFormFields","renderElement","element","type","label","addContent","Title","text","elements","forEach","scope","startsWith","error","meta","bindingPath","propKey","resolveScope","isCollectionOfRecords","items","properties","hasExplicitWidget","ui","widget","isSubLayout","debug","push","_renderScalarField","field","subSchema","control","generateLayout","addStyleClass","msg","message","showErrorPopup","labelText","Label","required","effectiveMeta","generateField","fullWidth","sap","require","GridData","setLayoutData","span","__exports","__esModule"],"sources":["FormLayout.ts"],"sourcesContent":["/**\n * @file FormLayout.ts\n * @description Generates a fully responsive SAP Fiori Form layout (SimpleForm).\n */\n\nimport SimpleForm from \"sap/ui/layout/form/SimpleForm\";\nimport Label from \"sap/m/Label\";\nimport Title from \"sap/ui/core/Title\";\nimport VBox from \"sap/m/VBox\";\nimport { IPropertyMetadata, ISchema, ILayoutElement } from \"../interfaces/ISchema\";\nimport { ILayoutManager } from \"../interfaces/ILayoutManager\";\nimport { Engine } from \"../core/Engine\";\nimport { SchemaNormalizer } from \"../core/SchemaNormalizer\";\nimport { Logger } from \"../utils/Logger\";\nimport Control from \"sap/ui/core/Control\";\n\n/**\n * Layout Manager responsible for generating a fully responsive SAP Fiori SimpleForm.\n * It traverses the `uiLayout` tree defined in the schema to build the form groups and fields,\n * completely separating visual orchestration from data modeling.\n * @namespace nz.co.siliconst.ui5.metaui.layouts\n * @public\n */\nexport class FormLayout implements ILayoutManager {\n /**\n * Renders the JSON Schema properties into a UI5 SimpleForm using the uiLayout definitions.\n * \n * @param schema The active JSON schema subset.\n * @param modelName The bound UI5 model name.\n * @param engine The central orchestrator for delegating plugin generation.\n * @param onSubmit Optional submit hook.\n * @returns {Control} The VBox wrapper containing the generated form.\n */\n public render(schema: ISchema, modelName: string, engine: Engine, onSubmit?: () => void): Control {\n const container = new VBox({ renderType: \"Bare\" });\n const form = new SimpleForm({\n editable: true,\n title: schema.title,\n layout: \"ResponsiveGridLayout\",\n labelSpanXL: 4, labelSpanL: 4, labelSpanM: 4, labelSpanS: 12,\n adjustLabelSpan: false,\n emptySpanXL: 0, emptySpanL: 0, emptySpanM: 0, emptySpanS: 0,\n columnsXL: 1, columnsL: 1, columnsM: 1,\n singleContainerFullSize: false\n });\n\n if (!schema.uiLayout || !Array.isArray(schema.uiLayout)) {\n Logger.warn(\"[MetaUI] Missing 'uiLayout' array in schema. Form will not render any fields.\");\n container.addItem(form);\n return container;\n }\n\n const tableElements: { scope: string, meta: IPropertyMetadata, label?: string }[] = [];\n let hasFormFields = false;\n\n // Recursively render layout elements\n const renderElement = (element: ILayoutElement) => {\n if (element.type === \"Group\") {\n if (element.label) {\n form.addContent(new Title({ text: element.label }));\n }\n \n if (element.elements && Array.isArray(element.elements)) {\n element.elements.forEach(renderElement);\n }\n } else if (element.type === \"Control\") {\n if (!element.scope || !element.scope.startsWith(\"#/properties/\")) {\n Logger.error(`[MetaUI] Invalid scope '${element.scope}' in uiLayout Control.`, \"\", \"FormLayout\");\n return;\n }\n \n const { meta, bindingPath, propKey } = SchemaNormalizer.resolveScope(schema, element.scope);\n \n if (!meta) {\n Logger.error(`[MetaUI] Property '${propKey}' not found in schema definitions.`, \"\", \"FormLayout\");\n return;\n }\n\n // Architectural Boundary: Separate Field Controls (Plugins) from Sub-Layouts (LayoutManagers)\n // A property is delegated to a Sub-Layout Manager (Table) ONLY if it represents a collection of complex objects.\n // Collections of primitives, or explicitly assigned widgets (like multiSelect), remain in the Form as Field Plugins.\n const isCollectionOfRecords = meta.items?.type === \"object\" || meta.items?.properties;\n const hasExplicitWidget = !!meta.ui?.widget;\n const isSubLayout = meta.type === \"array\" && isCollectionOfRecords && !hasExplicitWidget;\n\n if (isSubLayout) {\n Logger.debug(\"[MetaUI FormLayout]\", `Routing property '${propKey}' to Table Sub-Layout.`, \"FormLayout\");\n tableElements.push({ scope: bindingPath, meta, label: element.label });\n } else {\n hasFormFields = true;\n Logger.debug(\"[MetaUI FormLayout]\", `Rendering scalar field '${bindingPath}'.`, \"FormLayout\");\n this._renderScalarField(form, element, bindingPath, meta, modelName, engine);\n }\n } else {\n Logger.warn(`[MetaUI] Unsupported layout element type '${element.type}'.`, \"\", \"FormLayout\");\n }\n };\n\n // Render everything defined in the layout\n schema.uiLayout.forEach(renderElement);\n\n if (hasFormFields) {\n container.addItem(form);\n }\n\n // Render array/table sub-layouts full width below the form\n tableElements.forEach(field => {\n try {\n const subSchema = {\n type: \"array\",\n title: field.label || field.meta.ui?.label || field.scope,\n items: field.meta.items || { type: \"object\", properties: {} },\n uiLayout: field.meta.items?.uiLayout // Pass down sub-layout if available\n };\n \n const control = engine.generateLayout(subSchema as ISchema, modelName, `/${field.scope}`);\n if (control) {\n control.addStyleClass(\"sapUiSmallMarginTop\");\n container.addItem(control);\n }\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI] Failed to render array field ${field.scope}`, msg, \"FormLayout\");\n Logger.showErrorPopup(`Failed to render array field '${field.scope}'.\\n\\nDetails: ${msg}`);\n }\n });\n\n return container;\n }\n\n private _renderScalarField(form: SimpleForm, element: ILayoutElement, propKey: string, meta: IPropertyMetadata, modelName: string, engine: Engine): void {\n try {\n const labelText = element.label || meta.ui?.label || propKey;\n const label = new Label({\n text: labelText,\n required: meta.required\n });\n\n // Override widget if specified in the layout element\n const effectiveMeta = { ...meta };\n if (element.widget) {\n effectiveMeta.ui = { ...meta.ui, widget: element.widget };\n }\n\n const control = engine.generateField(effectiveMeta, `/${propKey}`, modelName);\n\n if (effectiveMeta.ui?.fullWidth) {\n sap.ui.require([\"sap/ui/layout/GridData\"], (GridData: any) => {\n control.setLayoutData(new GridData({ span: \"XL12 L12 M12 S12\" }));\n });\n }\n\n form.addContent(label);\n form.addContent(control);\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI] Failed to render field ${propKey}`, msg, \"FormLayout\");\n Logger.showErrorPopup(`Failed to render field '${propKey}'.\\n\\nDetails: ${msg}`);\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"FormLayout.d.ts","sourceRoot":"../../../../../../../..","sources":["src/nz/co/siliconst/ui5/metaui/layouts/FormLayout.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,+CAA+C,CAAC;IAU/D,OAAO,EAAqB,OAAO,EAAkB,MAAM,+CAA+C,CAAC;IAC3G,OAAO,EAAE,cAAc,EAAE,MAAM,sDAAsD,CAAC;IACtF,OAAO,EAAE,MAAM,EAAE,MAAM,wCAAwC,CAAC;IAEhE,OAAO,OAAO,MAAM,qBAAqB,CAAC;IAE1C;;;;;;OAMG;IACH,MAAa,UAAW,YAAW,cAAc;QAC7C;;;;;;;;WAQG;QACI,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO;QAkGjG,OAAO,CAAC,kBAAkB;KA8B7B;CAEA"}
1
+ {"version":3,"file":"FormLayout.d.ts","sourceRoot":"../../../../../../../..","sources":["src/nz/co/siliconst/ui5/metaui/layouts/FormLayout.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,+CAA+C,CAAC;IAU/D,OAAO,EAAqB,OAAO,EAAkB,MAAM,+CAA+C,CAAC;IAC3G,OAAO,EAAE,cAAc,EAAE,MAAM,sDAAsD,CAAC;IACtF,OAAO,EAAE,MAAM,EAAE,MAAM,wCAAwC,CAAC;IAGhE,OAAO,OAAO,MAAM,qBAAqB,CAAC;IAE1C;;;;;;OAMG;IACH,MAAa,UAAW,YAAW,cAAc;QAC7C;;;;;;;;WAQG;QACI,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO;QAiGjG,OAAO,CAAC,kBAAkB;KA8B7B;CAEA"}
@@ -1,2 +1,2 @@
1
- sap.ui.define(["sap/ui/layout/form/SimpleForm","sap/m/Label","sap/ui/core/Title","sap/m/VBox","../utils/Logger"],function(e,t,a,r,o){"use strict";const i=o["Logger"];class s{render(t,o,s,n){const l=new r({renderType:"Bare"});const u=new e({editable:true,title:t.title,layout:"ResponsiveGridLayout",labelSpanXL:4,labelSpanL:4,labelSpanM:4,labelSpanS:12,adjustLabelSpan:false,emptySpanXL:0,emptySpanL:0,emptySpanM:0,emptySpanS:0,columnsXL:1,columnsL:1,columnsM:1,singleContainerFullSize:false});if(!t.uiLayout||!Array.isArray(t.uiLayout)){i.warn("[MetaUI] Missing 'uiLayout' array in schema. Form will not render any fields.");l.addItem(u);return l}const p=[];let d=false;const y=e=>{if(e.type==="Group"){if(e.label){u.addContent(new a({text:e.label}))}if(e.elements&&Array.isArray(e.elements)){e.elements.forEach(y)}}else if(e.type==="Control"){if(!e.scope||!e.scope.startsWith("#/properties/")){i.error(`[MetaUI] Invalid scope '${e.scope}' in uiLayout Control.`,"","FormLayout");return}const a=e.scope.replace("#/properties/","");const r=t.properties?.[a];if(!r){i.error(`[MetaUI] Property '${a}' not found in schema definitions.`,"","FormLayout");return}const n=r.items?.type==="object"||r.items?.properties;const l=!!r.ui?.widget;const y=r.type==="array"&&n&&!l;if(y){i.debug("[MetaUI FormLayout]",`Routing property '${a}' to Table Sub-Layout.`,"FormLayout");p.push({scope:a,meta:r,label:e.label})}else{d=true;i.debug("[MetaUI FormLayout]",`Rendering scalar field '${a}'.`,"FormLayout");this._renderScalarField(u,e,a,r,o,s)}}else{i.warn(`[MetaUI] Unsupported layout element type '${e.type}'.`,"","FormLayout")}};t.uiLayout.forEach(y);if(d){l.addItem(u)}p.forEach(e=>{try{const t={type:"array",title:e.label||e.meta.ui?.label||e.scope,items:e.meta.items||{type:"object",properties:{}},uiLayout:e.meta.items?.uiLayout};const a=s.generateLayout(t,o,`/${e.scope}`);if(a){a.addStyleClass("sapUiSmallMarginTop");l.addItem(a)}}catch(t){const a=t.message;i.error(`[MetaUI] Failed to render array field ${e.scope}`,a,"FormLayout");i.showErrorPopup(`Failed to render array field '${e.scope}'.\n\nDetails: ${a}`)}});return l}_renderScalarField(e,a,r,o,s,n){try{const i=a.label||o.ui?.label||r;const l=new t({text:i,required:o.required});const u={...o};if(a.widget){u.ui={...o.ui,widget:a.widget}}const p=n.generateField(u,`/${r}`,s);if(u.ui?.fullWidth){sap.ui.require(["sap/ui/layout/GridData"],e=>{p.setLayoutData(new e({span:"XL12 L12 M12 S12"}))})}e.addContent(l);e.addContent(p)}catch(e){const t=e.message;i.error(`[MetaUI] Failed to render field ${r}`,t,"FormLayout");i.showErrorPopup(`Failed to render field '${r}'.\n\nDetails: ${t}`)}}}var n={__esModule:true};n.FormLayout=s;return n});
1
+ sap.ui.define(["sap/ui/layout/form/SimpleForm","sap/m/Label","sap/ui/core/Title","sap/m/VBox","../core/SchemaNormalizer","../utils/Logger"],function(e,t,a,r,o,i){"use strict";const n=o["SchemaNormalizer"];const s=i["Logger"];class l{render(t,o,i,l){const u=new r({renderType:"Bare"});const p=new e({editable:true,title:t.title,layout:"ResponsiveGridLayout",labelSpanXL:4,labelSpanL:4,labelSpanM:4,labelSpanS:12,adjustLabelSpan:false,emptySpanXL:0,emptySpanL:0,emptySpanM:0,emptySpanS:0,columnsXL:1,columnsL:1,columnsM:1,singleContainerFullSize:false});if(!t.uiLayout||!Array.isArray(t.uiLayout)){s.warn("[MetaUI] Missing 'uiLayout' array in schema. Form will not render any fields.");u.addItem(p);return u}const d=[];let y=false;const c=e=>{if(e.type==="Group"){if(e.label){p.addContent(new a({text:e.label}))}if(e.elements&&Array.isArray(e.elements)){e.elements.forEach(c)}}else if(e.type==="Control"){if(!e.scope||!e.scope.startsWith("#/properties/")){s.error(`[MetaUI] Invalid scope '${e.scope}' in uiLayout Control.`,"","FormLayout");return}const{meta:a,bindingPath:r,propKey:l}=n.resolveScope(t,e.scope);if(!a){s.error(`[MetaUI] Property '${l}' not found in schema definitions.`,"","FormLayout");return}const u=a.items?.type==="object"||a.items?.properties;const c=!!a.ui?.widget;const m=a.type==="array"&&u&&!c;if(m){s.debug("[MetaUI FormLayout]",`Routing property '${l}' to Table Sub-Layout.`,"FormLayout");d.push({scope:r,meta:a,label:e.label})}else{y=true;s.debug("[MetaUI FormLayout]",`Rendering scalar field '${r}'.`,"FormLayout");this._renderScalarField(p,e,r,a,o,i)}}else{s.warn(`[MetaUI] Unsupported layout element type '${e.type}'.`,"","FormLayout")}};t.uiLayout.forEach(c);if(y){u.addItem(p)}d.forEach(e=>{try{const t={type:"array",title:e.label||e.meta.ui?.label||e.scope,items:e.meta.items||{type:"object",properties:{}},uiLayout:e.meta.items?.uiLayout};const a=i.generateLayout(t,o,`/${e.scope}`);if(a){a.addStyleClass("sapUiSmallMarginTop");u.addItem(a)}}catch(t){const a=t.message;s.error(`[MetaUI] Failed to render array field ${e.scope}`,a,"FormLayout");s.showErrorPopup(`Failed to render array field '${e.scope}'.\n\nDetails: ${a}`)}});return u}_renderScalarField(e,a,r,o,i,n){try{const s=a.label||o.ui?.label||r;const l=new t({text:s,required:o.required});const u={...o};if(a.widget){u.ui={...o.ui,widget:a.widget}}const p=n.generateField(u,`/${r}`,i);if(u.ui?.fullWidth){sap.ui.require(["sap/ui/layout/GridData"],e=>{p.setLayoutData(new e({span:"XL12 L12 M12 S12"}))})}e.addContent(l);e.addContent(p)}catch(e){const t=e.message;s.error(`[MetaUI] Failed to render field ${r}`,t,"FormLayout");s.showErrorPopup(`Failed to render field '${r}'.\n\nDetails: ${t}`)}}}var u={__esModule:true};u.FormLayout=l;return u});
2
2
  //# sourceMappingURL=FormLayout.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"FormLayout.js","names":["Logger","___utils_Logger","FormLayout","render","schema","modelName","engine","onSubmit","container","VBox","renderType","form","SimpleForm","editable","title","layout","labelSpanXL","labelSpanL","labelSpanM","labelSpanS","adjustLabelSpan","emptySpanXL","emptySpanL","emptySpanM","emptySpanS","columnsXL","columnsL","columnsM","singleContainerFullSize","uiLayout","Array","isArray","warn","addItem","tableElements","hasFormFields","renderElement","element","type","label","addContent","Title","text","elements","forEach","scope","startsWith","error","propKey","replace","meta","properties","isCollectionOfRecords","items","hasExplicitWidget","ui","widget","isSubLayout","debug","push","this","_renderScalarField","field","subSchema","control","generateLayout","addStyleClass","msg","message","showErrorPopup","labelText","Label","required","effectiveMeta","generateField","fullWidth","sap","require","GridData","setLayoutData","span","__exports","__esModule"],"sources":["FormLayout.ts"],"sourcesContent":["/**\n * @file FormLayout.ts\n * @description Generates a fully responsive SAP Fiori Form layout (SimpleForm).\n */\n\nimport SimpleForm from \"sap/ui/layout/form/SimpleForm\";\nimport Label from \"sap/m/Label\";\nimport Title from \"sap/ui/core/Title\";\nimport VBox from \"sap/m/VBox\";\nimport { IPropertyMetadata, ISchema, ILayoutElement } from \"../interfaces/ISchema\";\nimport { ILayoutManager } from \"../interfaces/ILayoutManager\";\nimport { Engine } from \"../core/Engine\";\nimport { Logger } from \"../utils/Logger\";\nimport Control from \"sap/ui/core/Control\";\n\n/**\n * Layout Manager responsible for generating a fully responsive SAP Fiori SimpleForm.\n * It traverses the `uiLayout` tree defined in the schema to build the form groups and fields,\n * completely separating visual orchestration from data modeling.\n * @namespace nz.co.siliconst.ui5.metaui.layouts\n * @public\n */\nexport class FormLayout implements ILayoutManager {\n /**\n * Renders the JSON Schema properties into a UI5 SimpleForm using the uiLayout definitions.\n * \n * @param schema The active JSON schema subset.\n * @param modelName The bound UI5 model name.\n * @param engine The central orchestrator for delegating plugin generation.\n * @param onSubmit Optional submit hook.\n * @returns {Control} The VBox wrapper containing the generated form.\n */\n public render(schema: ISchema, modelName: string, engine: Engine, onSubmit?: () => void): Control {\n const container = new VBox({ renderType: \"Bare\" });\n const form = new SimpleForm({\n editable: true,\n title: schema.title,\n layout: \"ResponsiveGridLayout\",\n labelSpanXL: 4, labelSpanL: 4, labelSpanM: 4, labelSpanS: 12,\n adjustLabelSpan: false,\n emptySpanXL: 0, emptySpanL: 0, emptySpanM: 0, emptySpanS: 0,\n columnsXL: 1, columnsL: 1, columnsM: 1,\n singleContainerFullSize: false\n });\n\n if (!schema.uiLayout || !Array.isArray(schema.uiLayout)) {\n Logger.warn(\"[MetaUI] Missing 'uiLayout' array in schema. Form will not render any fields.\");\n container.addItem(form);\n return container;\n }\n\n const tableElements: { scope: string, meta: IPropertyMetadata, label?: string }[] = [];\n let hasFormFields = false;\n\n // Recursively render layout elements\n const renderElement = (element: ILayoutElement) => {\n if (element.type === \"Group\") {\n if (element.label) {\n form.addContent(new Title({ text: element.label }));\n }\n \n if (element.elements && Array.isArray(element.elements)) {\n element.elements.forEach(renderElement);\n }\n } else if (element.type === \"Control\") {\n if (!element.scope || !element.scope.startsWith(\"#/properties/\")) {\n Logger.error(`[MetaUI] Invalid scope '${element.scope}' in uiLayout Control.`, \"\", \"FormLayout\");\n return;\n }\n \n const propKey = element.scope.replace(\"#/properties/\", \"\");\n const meta = schema.properties?.[propKey];\n \n if (!meta) {\n Logger.error(`[MetaUI] Property '${propKey}' not found in schema definitions.`, \"\", \"FormLayout\");\n return;\n }\n\n // Architectural Boundary: Separate Field Controls (Plugins) from Sub-Layouts (LayoutManagers)\n // A property is delegated to a Sub-Layout Manager (Table) ONLY if it represents a collection of complex objects.\n // Collections of primitives, or explicitly assigned widgets (like multiSelect), remain in the Form as Field Plugins.\n const isCollectionOfRecords = meta.items?.type === \"object\" || meta.items?.properties;\n const hasExplicitWidget = !!meta.ui?.widget;\n const isSubLayout = meta.type === \"array\" && isCollectionOfRecords && !hasExplicitWidget;\n\n if (isSubLayout) {\n Logger.debug(\"[MetaUI FormLayout]\", `Routing property '${propKey}' to Table Sub-Layout.`, \"FormLayout\");\n tableElements.push({ scope: propKey, meta, label: element.label });\n } else {\n hasFormFields = true;\n Logger.debug(\"[MetaUI FormLayout]\", `Rendering scalar field '${propKey}'.`, \"FormLayout\");\n this._renderScalarField(form, element, propKey, meta, modelName, engine);\n }\n } else {\n Logger.warn(`[MetaUI] Unsupported layout element type '${element.type}'.`, \"\", \"FormLayout\");\n }\n };\n\n // Render everything defined in the layout\n schema.uiLayout.forEach(renderElement);\n\n if (hasFormFields) {\n container.addItem(form);\n }\n\n // Render array/table sub-layouts full width below the form\n tableElements.forEach(field => {\n try {\n const subSchema = {\n type: \"array\",\n title: field.label || field.meta.ui?.label || field.scope,\n items: field.meta.items || { type: \"object\", properties: {} },\n uiLayout: field.meta.items?.uiLayout // Pass down sub-layout if available\n };\n \n const control = engine.generateLayout(subSchema as ISchema, modelName, `/${field.scope}`);\n if (control) {\n control.addStyleClass(\"sapUiSmallMarginTop\");\n container.addItem(control);\n }\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI] Failed to render array field ${field.scope}`, msg, \"FormLayout\");\n Logger.showErrorPopup(`Failed to render array field '${field.scope}'.\\n\\nDetails: ${msg}`);\n }\n });\n\n return container;\n }\n\n private _renderScalarField(form: SimpleForm, element: ILayoutElement, propKey: string, meta: IPropertyMetadata, modelName: string, engine: Engine): void {\n try {\n const labelText = element.label || meta.ui?.label || propKey;\n const label = new Label({\n text: labelText,\n required: meta.required\n });\n\n // Override widget if specified in the layout element\n const effectiveMeta = { ...meta };\n if (element.widget) {\n effectiveMeta.ui = { ...meta.ui, widget: element.widget };\n }\n\n const control = engine.generateField(effectiveMeta, `/${propKey}`, modelName);\n\n if (effectiveMeta.ui?.fullWidth) {\n sap.ui.require([\"sap/ui/layout/GridData\"], (GridData: any) => {\n control.setLayoutData(new GridData({ span: \"XL12 L12 M12 S12\" }));\n });\n }\n\n form.addContent(label);\n form.addContent(control);\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI] Failed to render field ${propKey}`, msg, \"FormLayout\");\n Logger.showErrorPopup(`Failed to render field '${propKey}'.\\n\\nDetails: ${msg}`);\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"FormLayout.js","names":["SchemaNormalizer","___core_SchemaNormalizer","Logger","___utils_Logger","FormLayout","render","schema","modelName","engine","onSubmit","container","VBox","renderType","form","SimpleForm","editable","title","layout","labelSpanXL","labelSpanL","labelSpanM","labelSpanS","adjustLabelSpan","emptySpanXL","emptySpanL","emptySpanM","emptySpanS","columnsXL","columnsL","columnsM","singleContainerFullSize","uiLayout","Array","isArray","warn","addItem","tableElements","hasFormFields","renderElement","element","type","label","addContent","Title","text","elements","forEach","scope","startsWith","error","meta","bindingPath","propKey","resolveScope","isCollectionOfRecords","items","properties","hasExplicitWidget","ui","widget","isSubLayout","debug","push","this","_renderScalarField","field","subSchema","control","generateLayout","addStyleClass","msg","message","showErrorPopup","labelText","Label","required","effectiveMeta","generateField","fullWidth","sap","require","GridData","setLayoutData","span","__exports","__esModule"],"sources":["FormLayout.ts"],"sourcesContent":["/**\n * @file FormLayout.ts\n * @description Generates a fully responsive SAP Fiori Form layout (SimpleForm).\n */\n\nimport SimpleForm from \"sap/ui/layout/form/SimpleForm\";\nimport Label from \"sap/m/Label\";\nimport Title from \"sap/ui/core/Title\";\nimport VBox from \"sap/m/VBox\";\nimport { IPropertyMetadata, ISchema, ILayoutElement } from \"../interfaces/ISchema\";\nimport { ILayoutManager } from \"../interfaces/ILayoutManager\";\nimport { Engine } from \"../core/Engine\";\nimport { SchemaNormalizer } from \"../core/SchemaNormalizer\";\nimport { Logger } from \"../utils/Logger\";\nimport Control from \"sap/ui/core/Control\";\n\n/**\n * Layout Manager responsible for generating a fully responsive SAP Fiori SimpleForm.\n * It traverses the `uiLayout` tree defined in the schema to build the form groups and fields,\n * completely separating visual orchestration from data modeling.\n * @namespace nz.co.siliconst.ui5.metaui.layouts\n * @public\n */\nexport class FormLayout implements ILayoutManager {\n /**\n * Renders the JSON Schema properties into a UI5 SimpleForm using the uiLayout definitions.\n * \n * @param schema The active JSON schema subset.\n * @param modelName The bound UI5 model name.\n * @param engine The central orchestrator for delegating plugin generation.\n * @param onSubmit Optional submit hook.\n * @returns {Control} The VBox wrapper containing the generated form.\n */\n public render(schema: ISchema, modelName: string, engine: Engine, onSubmit?: () => void): Control {\n const container = new VBox({ renderType: \"Bare\" });\n const form = new SimpleForm({\n editable: true,\n title: schema.title,\n layout: \"ResponsiveGridLayout\",\n labelSpanXL: 4, labelSpanL: 4, labelSpanM: 4, labelSpanS: 12,\n adjustLabelSpan: false,\n emptySpanXL: 0, emptySpanL: 0, emptySpanM: 0, emptySpanS: 0,\n columnsXL: 1, columnsL: 1, columnsM: 1,\n singleContainerFullSize: false\n });\n\n if (!schema.uiLayout || !Array.isArray(schema.uiLayout)) {\n Logger.warn(\"[MetaUI] Missing 'uiLayout' array in schema. Form will not render any fields.\");\n container.addItem(form);\n return container;\n }\n\n const tableElements: { scope: string, meta: IPropertyMetadata, label?: string }[] = [];\n let hasFormFields = false;\n\n // Recursively render layout elements\n const renderElement = (element: ILayoutElement) => {\n if (element.type === \"Group\") {\n if (element.label) {\n form.addContent(new Title({ text: element.label }));\n }\n \n if (element.elements && Array.isArray(element.elements)) {\n element.elements.forEach(renderElement);\n }\n } else if (element.type === \"Control\") {\n if (!element.scope || !element.scope.startsWith(\"#/properties/\")) {\n Logger.error(`[MetaUI] Invalid scope '${element.scope}' in uiLayout Control.`, \"\", \"FormLayout\");\n return;\n }\n \n const { meta, bindingPath, propKey } = SchemaNormalizer.resolveScope(schema, element.scope);\n \n if (!meta) {\n Logger.error(`[MetaUI] Property '${propKey}' not found in schema definitions.`, \"\", \"FormLayout\");\n return;\n }\n\n // Architectural Boundary: Separate Field Controls (Plugins) from Sub-Layouts (LayoutManagers)\n // A property is delegated to a Sub-Layout Manager (Table) ONLY if it represents a collection of complex objects.\n // Collections of primitives, or explicitly assigned widgets (like multiSelect), remain in the Form as Field Plugins.\n const isCollectionOfRecords = meta.items?.type === \"object\" || meta.items?.properties;\n const hasExplicitWidget = !!meta.ui?.widget;\n const isSubLayout = meta.type === \"array\" && isCollectionOfRecords && !hasExplicitWidget;\n\n if (isSubLayout) {\n Logger.debug(\"[MetaUI FormLayout]\", `Routing property '${propKey}' to Table Sub-Layout.`, \"FormLayout\");\n tableElements.push({ scope: bindingPath, meta, label: element.label });\n } else {\n hasFormFields = true;\n Logger.debug(\"[MetaUI FormLayout]\", `Rendering scalar field '${bindingPath}'.`, \"FormLayout\");\n this._renderScalarField(form, element, bindingPath, meta, modelName, engine);\n }\n } else {\n Logger.warn(`[MetaUI] Unsupported layout element type '${element.type}'.`, \"\", \"FormLayout\");\n }\n };\n\n // Render everything defined in the layout\n schema.uiLayout.forEach(renderElement);\n\n if (hasFormFields) {\n container.addItem(form);\n }\n\n // Render array/table sub-layouts full width below the form\n tableElements.forEach(field => {\n try {\n const subSchema = {\n type: \"array\",\n title: field.label || field.meta.ui?.label || field.scope,\n items: field.meta.items || { type: \"object\", properties: {} },\n uiLayout: field.meta.items?.uiLayout // Pass down sub-layout if available\n };\n \n const control = engine.generateLayout(subSchema as ISchema, modelName, `/${field.scope}`);\n if (control) {\n control.addStyleClass(\"sapUiSmallMarginTop\");\n container.addItem(control);\n }\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI] Failed to render array field ${field.scope}`, msg, \"FormLayout\");\n Logger.showErrorPopup(`Failed to render array field '${field.scope}'.\\n\\nDetails: ${msg}`);\n }\n });\n\n return container;\n }\n\n private _renderScalarField(form: SimpleForm, element: ILayoutElement, propKey: string, meta: IPropertyMetadata, modelName: string, engine: Engine): void {\n try {\n const labelText = element.label || meta.ui?.label || propKey;\n const label = new Label({\n text: labelText,\n required: meta.required\n });\n\n // Override widget if specified in the layout element\n const effectiveMeta = { ...meta };\n if (element.widget) {\n effectiveMeta.ui = { ...meta.ui, widget: element.widget };\n }\n\n const control = engine.generateField(effectiveMeta, `/${propKey}`, modelName);\n\n if (effectiveMeta.ui?.fullWidth) {\n sap.ui.require([\"sap/ui/layout/GridData\"], (GridData: any) => {\n control.setLayoutData(new GridData({ span: \"XL12 L12 M12 S12\" }));\n });\n }\n\n form.addContent(label);\n form.addContent(control);\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI] Failed to render field ${propKey}`, msg, \"FormLayout\");\n Logger.showErrorPopup(`Failed to render field '${propKey}'.\\n\\nDetails: ${msg}`);\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -10,6 +10,7 @@ import VBox from "sap/m/VBox";
10
10
  import { IPropertyMetadata, ISchema, ILayoutElement } from "../interfaces/ISchema";
11
11
  import { ILayoutManager } from "../interfaces/ILayoutManager";
12
12
  import { Engine } from "../core/Engine";
13
+ import { SchemaNormalizer } from "../core/SchemaNormalizer";
13
14
  import { Logger } from "../utils/Logger";
14
15
  import Control from "sap/ui/core/Control";
15
16
 
@@ -68,8 +69,7 @@ export class FormLayout implements ILayoutManager {
68
69
  return;
69
70
  }
70
71
 
71
- const propKey = element.scope.replace("#/properties/", "");
72
- const meta = schema.properties?.[propKey];
72
+ const { meta, bindingPath, propKey } = SchemaNormalizer.resolveScope(schema, element.scope);
73
73
 
74
74
  if (!meta) {
75
75
  Logger.error(`[MetaUI] Property '${propKey}' not found in schema definitions.`, "", "FormLayout");
@@ -85,11 +85,11 @@ export class FormLayout implements ILayoutManager {
85
85
 
86
86
  if (isSubLayout) {
87
87
  Logger.debug("[MetaUI FormLayout]", `Routing property '${propKey}' to Table Sub-Layout.`, "FormLayout");
88
- tableElements.push({ scope: propKey, meta, label: element.label });
88
+ tableElements.push({ scope: bindingPath, meta, label: element.label });
89
89
  } else {
90
90
  hasFormFields = true;
91
- Logger.debug("[MetaUI FormLayout]", `Rendering scalar field '${propKey}'.`, "FormLayout");
92
- this._renderScalarField(form, element, propKey, meta, modelName, engine);
91
+ Logger.debug("[MetaUI FormLayout]", `Rendering scalar field '${bindingPath}'.`, "FormLayout");
92
+ this._renderScalarField(form, element, bindingPath, meta, modelName, engine);
93
93
  }
94
94
  } else {
95
95
  Logger.warn(`[MetaUI] Unsupported layout element type '${element.type}'.`, "", "FormLayout");