@siliconst/metaui 1.4.4 → 1.4.6

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 (204) hide show
  1. package/package.json +1 -1
  2. package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost-dbg.js +42 -3
  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 +7 -1
  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 +45 -1
  9. package/src/nz/co/siliconst/ui5/metaui/controls/host/GeneratorHost-dbg.js +5 -5
  10. package/src/nz/co/siliconst/ui5/metaui/controls/host/GeneratorHost-dbg.js.map +1 -1
  11. package/src/nz/co/siliconst/ui5/metaui/controls/host/GeneratorHost.d.ts +1 -1
  12. package/src/nz/co/siliconst/ui5/metaui/controls/host/GeneratorHost.js +1 -1
  13. package/src/nz/co/siliconst/ui5/metaui/controls/host/GeneratorHost.js.map +1 -1
  14. package/src/nz/co/siliconst/ui5/metaui/controls/host/GeneratorHost.ts +4 -4
  15. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ODataDelegate-dbg.js +122 -0
  16. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ODataDelegate-dbg.js.map +1 -0
  17. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ODataDelegate.d.ts +49 -0
  18. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ODataDelegate.d.ts.map +1 -0
  19. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ODataDelegate.js +2 -0
  20. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ODataDelegate.js.map +1 -0
  21. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ODataDelegate.ts +118 -0
  22. package/src/nz/co/siliconst/ui5/metaui/core/DefaultLayoutGenerator-dbg.js +24 -8
  23. package/src/nz/co/siliconst/ui5/metaui/core/DefaultLayoutGenerator-dbg.js.map +1 -1
  24. package/src/nz/co/siliconst/ui5/metaui/core/DefaultLayoutGenerator.d.ts +1 -0
  25. package/src/nz/co/siliconst/ui5/metaui/core/DefaultLayoutGenerator.d.ts.map +1 -1
  26. package/src/nz/co/siliconst/ui5/metaui/core/DefaultLayoutGenerator.js +1 -1
  27. package/src/nz/co/siliconst/ui5/metaui/core/DefaultLayoutGenerator.js.map +1 -1
  28. package/src/nz/co/siliconst/ui5/metaui/core/DefaultLayoutGenerator.ts +26 -9
  29. package/src/nz/co/siliconst/ui5/metaui/core/Engine-dbg.js +5 -5
  30. package/src/nz/co/siliconst/ui5/metaui/core/Engine-dbg.js.map +1 -1
  31. package/src/nz/co/siliconst/ui5/metaui/core/Engine.d.ts +3 -3
  32. package/src/nz/co/siliconst/ui5/metaui/core/Engine.d.ts.map +1 -1
  33. package/src/nz/co/siliconst/ui5/metaui/core/Engine.js +1 -1
  34. package/src/nz/co/siliconst/ui5/metaui/core/Engine.js.map +1 -1
  35. package/src/nz/co/siliconst/ui5/metaui/core/Engine.ts +5 -5
  36. package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer-dbg.js +45 -1
  37. package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer-dbg.js.map +1 -1
  38. package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer.d.ts +10 -1
  39. package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer.d.ts.map +1 -1
  40. package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer.js +1 -1
  41. package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer.js.map +1 -1
  42. package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer.ts +45 -2
  43. package/src/nz/co/siliconst/ui5/metaui/interfaces/IPlugin-dbg.js.map +1 -1
  44. package/src/nz/co/siliconst/ui5/metaui/interfaces/IPlugin.d.ts +3 -3
  45. package/src/nz/co/siliconst/ui5/metaui/interfaces/IPlugin.d.ts.map +1 -1
  46. package/src/nz/co/siliconst/ui5/metaui/interfaces/IPlugin.ts +3 -3
  47. package/src/nz/co/siliconst/ui5/metaui/layouts/CompactLayout-dbg.js +10 -6
  48. package/src/nz/co/siliconst/ui5/metaui/layouts/CompactLayout-dbg.js.map +1 -1
  49. package/src/nz/co/siliconst/ui5/metaui/layouts/CompactLayout.d.ts.map +1 -1
  50. package/src/nz/co/siliconst/ui5/metaui/layouts/CompactLayout.js +1 -1
  51. package/src/nz/co/siliconst/ui5/metaui/layouts/CompactLayout.js.map +1 -1
  52. package/src/nz/co/siliconst/ui5/metaui/layouts/CompactLayout.ts +5 -5
  53. package/src/nz/co/siliconst/ui5/metaui/layouts/FormLayout-dbg.js +10 -6
  54. package/src/nz/co/siliconst/ui5/metaui/layouts/FormLayout-dbg.js.map +1 -1
  55. package/src/nz/co/siliconst/ui5/metaui/layouts/FormLayout.d.ts.map +1 -1
  56. package/src/nz/co/siliconst/ui5/metaui/layouts/FormLayout.js +1 -1
  57. package/src/nz/co/siliconst/ui5/metaui/layouts/FormLayout.js.map +1 -1
  58. package/src/nz/co/siliconst/ui5/metaui/layouts/FormLayout.ts +5 -5
  59. package/src/nz/co/siliconst/ui5/metaui/layouts/TableLayout-dbg.js +24 -31
  60. package/src/nz/co/siliconst/ui5/metaui/layouts/TableLayout-dbg.js.map +1 -1
  61. package/src/nz/co/siliconst/ui5/metaui/layouts/TableLayout.d.ts.map +1 -1
  62. package/src/nz/co/siliconst/ui5/metaui/layouts/TableLayout.js +1 -1
  63. package/src/nz/co/siliconst/ui5/metaui/layouts/TableLayout.js.map +1 -1
  64. package/src/nz/co/siliconst/ui5/metaui/layouts/TableLayout.ts +20 -31
  65. package/src/nz/co/siliconst/ui5/metaui/layouts/WizardLayout-dbg.js +8 -4
  66. package/src/nz/co/siliconst/ui5/metaui/layouts/WizardLayout-dbg.js.map +1 -1
  67. package/src/nz/co/siliconst/ui5/metaui/layouts/WizardLayout.d.ts.map +1 -1
  68. package/src/nz/co/siliconst/ui5/metaui/layouts/WizardLayout.js +1 -1
  69. package/src/nz/co/siliconst/ui5/metaui/layouts/WizardLayout.js.map +1 -1
  70. package/src/nz/co/siliconst/ui5/metaui/layouts/WizardLayout.ts +3 -3
  71. package/src/nz/co/siliconst/ui5/metaui/library-preload.js +36 -35
  72. package/src/nz/co/siliconst/ui5/metaui/library-preload.js.map +1 -1
  73. package/src/nz/co/siliconst/ui5/metaui/plugins/actions/ClearFormActionPlugin-dbg.js +2 -2
  74. package/src/nz/co/siliconst/ui5/metaui/plugins/actions/ClearFormActionPlugin-dbg.js.map +1 -1
  75. package/src/nz/co/siliconst/ui5/metaui/plugins/actions/ClearFormActionPlugin.js +1 -1
  76. package/src/nz/co/siliconst/ui5/metaui/plugins/actions/ClearFormActionPlugin.js.map +1 -1
  77. package/src/nz/co/siliconst/ui5/metaui/plugins/actions/ClearFormActionPlugin.ts +2 -2
  78. package/src/nz/co/siliconst/ui5/metaui/plugins/actions/SubmitFormActionPlugin-dbg.js +2 -2
  79. package/src/nz/co/siliconst/ui5/metaui/plugins/actions/SubmitFormActionPlugin-dbg.js.map +1 -1
  80. package/src/nz/co/siliconst/ui5/metaui/plugins/actions/SubmitFormActionPlugin.js +1 -1
  81. package/src/nz/co/siliconst/ui5/metaui/plugins/actions/SubmitFormActionPlugin.js.map +1 -1
  82. package/src/nz/co/siliconst/ui5/metaui/plugins/actions/SubmitFormActionPlugin.ts +2 -2
  83. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ArrayPlugin-dbg.js +5 -5
  84. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ArrayPlugin-dbg.js.map +1 -1
  85. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ArrayPlugin.js +1 -1
  86. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ArrayPlugin.js.map +1 -1
  87. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ArrayPlugin.ts +5 -5
  88. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BarcodeScannerPlugin-dbg.js +2 -2
  89. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BarcodeScannerPlugin-dbg.js.map +1 -1
  90. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BarcodeScannerPlugin.js +1 -1
  91. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BarcodeScannerPlugin.js.map +1 -1
  92. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BarcodeScannerPlugin.ts +2 -2
  93. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BasePlugin-dbg.js +6 -6
  94. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BasePlugin-dbg.js.map +1 -1
  95. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BasePlugin.d.ts +5 -5
  96. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BasePlugin.d.ts.map +1 -1
  97. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BasePlugin.js +1 -1
  98. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BasePlugin.js.map +1 -1
  99. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BasePlugin.ts +6 -6
  100. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BooleanPlugin-dbg.js +2 -2
  101. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BooleanPlugin-dbg.js.map +1 -1
  102. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BooleanPlugin.js +1 -1
  103. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BooleanPlugin.js.map +1 -1
  104. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BooleanPlugin.ts +2 -2
  105. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CameraPlugin-dbg.js +2 -2
  106. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CameraPlugin-dbg.js.map +1 -1
  107. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CameraPlugin.js +1 -1
  108. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CameraPlugin.js.map +1 -1
  109. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CameraPlugin.ts +2 -2
  110. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CodeEditorPlugin-dbg.js +2 -2
  111. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CodeEditorPlugin-dbg.js.map +1 -1
  112. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CodeEditorPlugin.js +1 -1
  113. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CodeEditorPlugin.js.map +1 -1
  114. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CodeEditorPlugin.ts +2 -2
  115. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DatePlugin-dbg.js +2 -2
  116. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DatePlugin-dbg.js.map +1 -1
  117. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DatePlugin.js +1 -1
  118. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DatePlugin.js.map +1 -1
  119. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DatePlugin.ts +2 -2
  120. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DateTimePlugin-dbg.js +2 -2
  121. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DateTimePlugin-dbg.js.map +1 -1
  122. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DateTimePlugin.js +1 -1
  123. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DateTimePlugin.js.map +1 -1
  124. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DateTimePlugin.ts +2 -2
  125. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DropdownPlugin-dbg.js +2 -2
  126. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DropdownPlugin-dbg.js.map +1 -1
  127. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DropdownPlugin.js +1 -1
  128. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DropdownPlugin.js.map +1 -1
  129. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DropdownPlugin.ts +2 -2
  130. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/FileUploaderPlugin-dbg.js +2 -2
  131. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/FileUploaderPlugin-dbg.js.map +1 -1
  132. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/FileUploaderPlugin.js +1 -1
  133. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/FileUploaderPlugin.js.map +1 -1
  134. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/FileUploaderPlugin.ts +2 -2
  135. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/GeolocationPlugin-dbg.js +2 -2
  136. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/GeolocationPlugin-dbg.js.map +1 -1
  137. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/GeolocationPlugin.js +1 -1
  138. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/GeolocationPlugin.js.map +1 -1
  139. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/GeolocationPlugin.ts +2 -2
  140. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MultiSelectPlugin-dbg.js +2 -2
  141. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MultiSelectPlugin-dbg.js.map +1 -1
  142. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MultiSelectPlugin.js +1 -1
  143. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MultiSelectPlugin.js.map +1 -1
  144. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MultiSelectPlugin.ts +2 -2
  145. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/NumberPlugin-dbg.js +2 -2
  146. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/NumberPlugin-dbg.js.map +1 -1
  147. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/NumberPlugin.js +1 -1
  148. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/NumberPlugin.js.map +1 -1
  149. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/NumberPlugin.ts +2 -2
  150. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ObjectPlugin-dbg.js +5 -5
  151. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ObjectPlugin-dbg.js.map +1 -1
  152. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ObjectPlugin.js +1 -1
  153. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ObjectPlugin.js.map +1 -1
  154. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ObjectPlugin.ts +5 -5
  155. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/RatingIndicatorPlugin-dbg.js +2 -2
  156. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/RatingIndicatorPlugin-dbg.js.map +1 -1
  157. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/RatingIndicatorPlugin.js +1 -1
  158. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/RatingIndicatorPlugin.js.map +1 -1
  159. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/RatingIndicatorPlugin.ts +2 -2
  160. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/RichTextPlugin-dbg.js +2 -2
  161. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/RichTextPlugin-dbg.js.map +1 -1
  162. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/RichTextPlugin.js +1 -1
  163. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/RichTextPlugin.js.map +1 -1
  164. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/RichTextPlugin.ts +2 -2
  165. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SignaturePlugin-dbg.js +2 -2
  166. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SignaturePlugin-dbg.js.map +1 -1
  167. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SignaturePlugin.js +1 -1
  168. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SignaturePlugin.js.map +1 -1
  169. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SignaturePlugin.ts +2 -2
  170. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SliderPlugin-dbg.js +2 -2
  171. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SliderPlugin-dbg.js.map +1 -1
  172. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SliderPlugin.js +1 -1
  173. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SliderPlugin.js.map +1 -1
  174. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SliderPlugin.ts +2 -2
  175. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/StringPlugin-dbg.js +2 -2
  176. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/StringPlugin-dbg.js.map +1 -1
  177. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/StringPlugin.js +1 -1
  178. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/StringPlugin.js.map +1 -1
  179. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/StringPlugin.ts +2 -2
  180. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SwitchPlugin-dbg.js +2 -2
  181. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SwitchPlugin-dbg.js.map +1 -1
  182. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SwitchPlugin.js +1 -1
  183. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SwitchPlugin.js.map +1 -1
  184. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SwitchPlugin.ts +2 -2
  185. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TextAreaPlugin-dbg.js +2 -2
  186. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TextAreaPlugin-dbg.js.map +1 -1
  187. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TextAreaPlugin.js +1 -1
  188. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TextAreaPlugin.js.map +1 -1
  189. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TextAreaPlugin.ts +2 -2
  190. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TimePlugin-dbg.js +2 -2
  191. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TimePlugin-dbg.js.map +1 -1
  192. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TimePlugin.js +1 -1
  193. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TimePlugin.js.map +1 -1
  194. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TimePlugin.ts +2 -2
  195. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/VoiceInputPlugin-dbg.js +2 -2
  196. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/VoiceInputPlugin-dbg.js.map +1 -1
  197. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/VoiceInputPlugin.js +1 -1
  198. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/VoiceInputPlugin.js.map +1 -1
  199. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/VoiceInputPlugin.ts +2 -2
  200. package/src/nz/co/siliconst/ui5/metaui/plugins/datasources/RemoteDropdownPlugin-dbg.js +2 -2
  201. package/src/nz/co/siliconst/ui5/metaui/plugins/datasources/RemoteDropdownPlugin-dbg.js.map +1 -1
  202. package/src/nz/co/siliconst/ui5/metaui/plugins/datasources/RemoteDropdownPlugin.js +1 -1
  203. package/src/nz/co/siliconst/ui5/metaui/plugins/datasources/RemoteDropdownPlugin.js.map +1 -1
  204. package/src/nz/co/siliconst/ui5/metaui/plugins/datasources/RemoteDropdownPlugin.ts +2 -2
@@ -0,0 +1,118 @@
1
+ import { DynamicHost } from "../DynamicHost";
2
+ import Context from "sap/ui/model/Context";
3
+ import { Logger } from "../../../utils/Logger";
4
+
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
+ export class ODataDelegate {
11
+ private host: DynamicHost;
12
+ private context: Context;
13
+ private odataType: "V2" | "V4" | null = null;
14
+ private isSyncing: boolean = false;
15
+
16
+ /**
17
+ * Initializes a new instance of the ODataDelegate.
18
+ *
19
+ * @param {DynamicHost} host The parent MetaUI DynamicHost instance managing the UI generation.
20
+ * @param {Context} context The active UI5 Model Context bound to the host.
21
+ */
22
+ constructor(host: DynamicHost, context: Context) {
23
+ this.host = host;
24
+ this.context = context;
25
+ this.detectODataType();
26
+ }
27
+
28
+ /**
29
+ * Evaluates the underlying UI5 Model bound to the context to determine if it is an
30
+ * OData V2 or OData V4 model. This determination drives the synchronization strategy.
31
+ *
32
+ * @private
33
+ */
34
+ private detectODataType(): void {
35
+ const model = this.context.getModel();
36
+ // sap.ui.model.odata.v4.ODataModel
37
+ // sap.ui.model.odata.v2.ODataModel
38
+ const sClassName = model.getMetadata().getName();
39
+ if (sClassName.indexOf("v4") > -1) {
40
+ this.odataType = "V4";
41
+ } else if (sClassName.indexOf("v2") > -1 || sClassName.indexOf("ODataModel") > -1) {
42
+ this.odataType = "V2";
43
+ }
44
+ }
45
+
46
+ /**
47
+ * Extracts the full entity payload from the bound OData context and pushes it to the Engine.
48
+ * V4 uses an asynchronous requestObject(), while V2 retrieves it synchronously.
49
+ *
50
+ * @public
51
+ */
52
+ public syncToEngine(): void {
53
+ if (!this.odataType) return;
54
+
55
+ if (this.odataType === "V4") {
56
+ // V4 uses async requestObject()
57
+ if (typeof (this.context as any).requestObject === "function") {
58
+ (this.context as any).requestObject().then((oData: any) => {
59
+ this.pushPayload(oData);
60
+ }).catch((err: Error) => {
61
+ Logger.error("[MetaUI]", "Failed to extract V4 Context payload: " + err.message, "ODataDelegate");
62
+ });
63
+ }
64
+ } else if (this.odataType === "V2") {
65
+ // V2 uses sync getObject()
66
+ const oData = this.context.getObject();
67
+ if (oData) {
68
+ this.pushPayload(oData);
69
+ }
70
+ }
71
+ }
72
+
73
+ /**
74
+ * Cleans the raw OData payload by stripping framework metadata properties (keys starting with '@' or '__')
75
+ * and pushes the sanitized business data into the MetaUI DynamicHost state manager.
76
+ *
77
+ * @param {any} oData The raw JSON object extracted from the OData model context.
78
+ * @private
79
+ */
80
+ private pushPayload(oData: any): void {
81
+ if (!oData) return;
82
+
83
+ // Remove OData metadata properties before pushing to MetaUI
84
+ const cleanData = { ...oData };
85
+ for (const key of Object.keys(cleanData)) {
86
+ if (key.startsWith("@") || key.startsWith("__")) {
87
+ delete cleanData[key];
88
+ }
89
+ }
90
+
91
+ this.isSyncing = true;
92
+ this.host.setProperty("data", cleanData);
93
+ this.isSyncing = false;
94
+ }
95
+
96
+ /**
97
+ * Intercepts a field change from the MetaUI Engine and translates it into an OData PATCH.
98
+ */
99
+ public handleFieldChange(fieldPath: string, value: any): void {
100
+ if (this.isSyncing || !this.odataType) return;
101
+
102
+ try {
103
+ if (this.odataType === "V4") {
104
+ // V4 sets property directly on context
105
+ this.context.setProperty(fieldPath, value);
106
+ } else if (this.odataType === "V2") {
107
+ // V2 sets property on model, specifying the context path
108
+ const model = this.context.getModel();
109
+ model.setProperty(fieldPath, value, this.context);
110
+ }
111
+ if (this.host.getProperty("debugMode")) {
112
+ Logger.debug("[MetaUI]", `ODataDelegate Patched ${fieldPath} = ${value} via ${this.odataType}`, "ODataDelegate");
113
+ }
114
+ } catch (e) {
115
+ Logger.error("[MetaUI]", `Failed to patch OData context: ${(e as Error).message}`, "ODataDelegate");
116
+ }
117
+ }
118
+ }
@@ -32,16 +32,12 @@ sap.ui.define([], function () {
32
32
  if (!props || Object.keys(props).length === 0) {
33
33
  return false; // Nothing to map
34
34
  }
35
- const elements = [];
36
- for (const key of Object.keys(props)) {
37
- elements.push({
38
- type: "Control",
39
- scope: `#/properties/${key}`
40
- });
41
- }
35
+ const elements = this.generateElementsFromProperties(props, "#/properties");
42
36
  if (isArray) {
43
37
  // Table layouts expect an array of flat Controls at the root uiLayout
44
- schema.uiLayout = elements;
38
+ // For tables, we flatten the deep elements or just render the root level
39
+ // To keep it safe, we'll just use the flat elements for tables
40
+ schema.uiLayout = elements.filter(e => e.type === "Control");
45
41
  } else {
46
42
  // Form layouts expect a grouped structure
47
43
  schema.uiLayout = [{
@@ -52,6 +48,26 @@ sap.ui.define([], function () {
52
48
  }
53
49
  return true;
54
50
  }
51
+ static generateElementsFromProperties(props, basePath) {
52
+ const elements = [];
53
+ for (const key of Object.keys(props)) {
54
+ const prop = props[key];
55
+ const currentPath = `${basePath}/${key}`;
56
+ if (prop.type === "object" && prop.properties) {
57
+ elements.push({
58
+ type: "Group",
59
+ label: prop.ui?.label || key,
60
+ elements: this.generateElementsFromProperties(prop.properties, `${currentPath}/properties`)
61
+ });
62
+ } else {
63
+ elements.push({
64
+ type: "Control",
65
+ scope: currentPath
66
+ });
67
+ }
68
+ }
69
+ return elements;
70
+ }
55
71
  }
56
72
  var __exports = {
57
73
  __esModule: true
@@ -1 +1 @@
1
- {"version":3,"file":"DefaultLayoutGenerator-dbg.js","names":["DefaultLayoutGenerator","ensureLayout","schema","uiLayout","Array","isArray","length","type","props","items","properties","Object","keys","elements","key","push","scope","label","title","__exports","__esModule"],"sources":["DefaultLayoutGenerator.ts"],"sourcesContent":["/**\n * @file DefaultLayoutGenerator.ts\n * @description Automatically synthesizes a default UI layout for schemas that lack an explicit mapping.\n */\n\nimport { ISchema, ILayoutElement } from \"../interfaces/ISchema\";\n\n/**\n * Encapsulates the logic to dynamically build a safe, default layout orchestration\n * when the developer or backend fails to provide an explicit `uiLayout`.\n * \n * By elevating this into a dedicated utility, we avoid polluting layout engines\n * (like FormLayout or TableLayout) with structural inference responsibilities.\n * \n * @namespace nz.co.siliconst.ui5.metaui.core\n * @public\n */\nexport class DefaultLayoutGenerator {\n /**\n * Inspects a schema. If it has properties but no `uiLayout`, it synthesizes a default.\n * @param schema The ISchema dictionary.\n * @returns boolean True if a layout was synthesized, false if it already existed or was empty.\n */\n public static ensureLayout(schema: ISchema): boolean {\n // If it already has a valid array, do nothing\n if (schema.uiLayout && Array.isArray(schema.uiLayout) && schema.uiLayout.length > 0) {\n return false;\n }\n\n const isArray = schema.type === \"array\";\n const props = isArray ? schema.items?.properties : schema.properties;\n\n if (!props || Object.keys(props).length === 0) {\n return false; // Nothing to map\n }\n\n const elements: ILayoutElement[] = [];\n\n for (const key of Object.keys(props)) {\n elements.push({\n type: \"Control\",\n scope: `#/properties/${key}`\n });\n }\n\n if (isArray) {\n // Table layouts expect an array of flat Controls at the root uiLayout\n schema.uiLayout = elements;\n } else {\n // Form layouts expect a grouped structure\n schema.uiLayout = [\n {\n type: \"Group\",\n label: schema.title,\n elements: elements\n }\n ];\n }\n\n return true;\n }\n}\n"],"mappings":";;;EAAA;AACA;AACA;AACA;;EAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACO,MAAMA,sBAAsB,CAAC;IAChC;AACJ;AACA;AACA;AACA;IACI,OAAcC,YAAYA,CAACC,MAAe,EAAW;MACjD;MACA,IAAIA,MAAM,CAACC,QAAQ,IAAIC,KAAK,CAACC,OAAO,CAACH,MAAM,CAACC,QAAQ,CAAC,IAAID,MAAM,CAACC,QAAQ,CAACG,MAAM,GAAG,CAAC,EAAE;QACjF,OAAO,KAAK;MAChB;MAEA,MAAMD,OAAO,GAAGH,MAAM,CAACK,IAAI,KAAK,OAAO;MACvC,MAAMC,KAAK,GAAGH,OAAO,GAAGH,MAAM,CAACO,KAAK,EAAEC,UAAU,GAAGR,MAAM,CAACQ,UAAU;MAEpE,IAAI,CAACF,KAAK,IAAIG,MAAM,CAACC,IAAI,CAACJ,KAAK,CAAC,CAACF,MAAM,KAAK,CAAC,EAAE;QAC3C,OAAO,KAAK,CAAC,CAAC;MAClB;MAEA,MAAMO,QAA0B,GAAG,EAAE;MAErC,KAAK,MAAMC,GAAG,IAAIH,MAAM,CAACC,IAAI,CAACJ,KAAK,CAAC,EAAE;QAClCK,QAAQ,CAACE,IAAI,CAAC;UACVR,IAAI,EAAE,SAAS;UACfS,KAAK,EAAE,gBAAgBF,GAAG;QAC9B,CAAC,CAAC;MACN;MAEA,IAAIT,OAAO,EAAE;QACT;QACAH,MAAM,CAACC,QAAQ,GAAGU,QAAQ;MAC9B,CAAC,MAAM;QACH;QACAX,MAAM,CAACC,QAAQ,GAAG,CACd;UACII,IAAI,EAAE,OAAO;UACbU,KAAK,EAAEf,MAAM,CAACgB,KAAK;UACnBL,QAAQ,EAAEA;QACd,CAAC,CACJ;MACL;MAEA,OAAO,IAAI;IACf;EACJ;EAAC,IAAAM,SAAA;IAAAC,UAAA;EAAA;EAAAD,SAAA,CAAAnB,sBAAA,GAAAA,sBAAA;EAAA,OAAAmB,SAAA;AAAA","ignoreList":[]}
1
+ {"version":3,"file":"DefaultLayoutGenerator-dbg.js","names":["DefaultLayoutGenerator","ensureLayout","schema","uiLayout","Array","isArray","length","type","props","items","properties","Object","keys","elements","generateElementsFromProperties","filter","e","label","title","basePath","key","prop","currentPath","push","ui","scope","__exports","__esModule"],"sources":["DefaultLayoutGenerator.ts"],"sourcesContent":["/**\n * @file DefaultLayoutGenerator.ts\n * @description Automatically synthesizes a default UI layout for schemas that lack an explicit mapping.\n */\n\nimport { ISchema, ILayoutElement } from \"../interfaces/ISchema\";\n\n/**\n * Encapsulates the logic to dynamically build a safe, default layout orchestration\n * when the developer or backend fails to provide an explicit `uiLayout`.\n * \n * By elevating this into a dedicated utility, we avoid polluting layout engines\n * (like FormLayout or TableLayout) with structural inference responsibilities.\n * \n * @namespace nz.co.siliconst.ui5.metaui.core\n * @public\n */\nexport class DefaultLayoutGenerator {\n /**\n * Inspects a schema. If it has properties but no `uiLayout`, it synthesizes a default.\n * @param schema The ISchema dictionary.\n * @returns boolean True if a layout was synthesized, false if it already existed or was empty.\n */\n public static ensureLayout(schema: ISchema): boolean {\n // If it already has a valid array, do nothing\n if (schema.uiLayout && Array.isArray(schema.uiLayout) && schema.uiLayout.length > 0) {\n return false;\n }\n\n const isArray = schema.type === \"array\";\n const props = isArray ? schema.items?.properties : schema.properties;\n\n if (!props || Object.keys(props).length === 0) {\n return false; // Nothing to map\n }\n\n const elements = this.generateElementsFromProperties(props, \"#/properties\");\n\n if (isArray) {\n // Table layouts expect an array of flat Controls at the root uiLayout\n // For tables, we flatten the deep elements or just render the root level\n // To keep it safe, we'll just use the flat elements for tables\n schema.uiLayout = elements.filter(e => e.type === \"Control\");\n } else {\n // Form layouts expect a grouped structure\n schema.uiLayout = [\n {\n type: \"Group\",\n label: schema.title,\n elements: elements\n }\n ];\n }\n\n return true;\n }\n\n private static generateElementsFromProperties(props: any, basePath: string): ILayoutElement[] {\n const elements: ILayoutElement[] = [];\n for (const key of Object.keys(props)) {\n const prop = props[key];\n const currentPath = `${basePath}/${key}`;\n\n if (prop.type === \"object\" && prop.properties) {\n elements.push({\n type: \"Group\",\n label: prop.ui?.label || key,\n elements: this.generateElementsFromProperties(prop.properties, `${currentPath}/properties`)\n });\n } else {\n elements.push({\n type: \"Control\",\n scope: currentPath\n });\n }\n }\n return elements;\n }\n}\n"],"mappings":";;;EAAA;AACA;AACA;AACA;;EAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACO,MAAMA,sBAAsB,CAAC;IAChC;AACJ;AACA;AACA;AACA;IACI,OAAcC,YAAYA,CAACC,MAAe,EAAW;MACjD;MACA,IAAIA,MAAM,CAACC,QAAQ,IAAIC,KAAK,CAACC,OAAO,CAACH,MAAM,CAACC,QAAQ,CAAC,IAAID,MAAM,CAACC,QAAQ,CAACG,MAAM,GAAG,CAAC,EAAE;QACjF,OAAO,KAAK;MAChB;MAEA,MAAMD,OAAO,GAAGH,MAAM,CAACK,IAAI,KAAK,OAAO;MACvC,MAAMC,KAAK,GAAGH,OAAO,GAAGH,MAAM,CAACO,KAAK,EAAEC,UAAU,GAAGR,MAAM,CAACQ,UAAU;MAEpE,IAAI,CAACF,KAAK,IAAIG,MAAM,CAACC,IAAI,CAACJ,KAAK,CAAC,CAACF,MAAM,KAAK,CAAC,EAAE;QAC3C,OAAO,KAAK,CAAC,CAAC;MAClB;MAEA,MAAMO,QAAQ,GAAG,IAAI,CAACC,8BAA8B,CAACN,KAAK,EAAE,cAAc,CAAC;MAE3E,IAAIH,OAAO,EAAE;QACT;QACA;QACA;QACAH,MAAM,CAACC,QAAQ,GAAGU,QAAQ,CAACE,MAAM,CAACC,CAAC,IAAIA,CAAC,CAACT,IAAI,KAAK,SAAS,CAAC;MAChE,CAAC,MAAM;QACH;QACAL,MAAM,CAACC,QAAQ,GAAG,CACd;UACII,IAAI,EAAE,OAAO;UACbU,KAAK,EAAEf,MAAM,CAACgB,KAAK;UACnBL,QAAQ,EAAEA;QACd,CAAC,CACJ;MACL;MAEA,OAAO,IAAI;IACf;IAEA,OAAeC,8BAA8BA,CAACN,KAAU,EAAEW,QAAgB,EAAoB;MAC1F,MAAMN,QAA0B,GAAG,EAAE;MACrC,KAAK,MAAMO,GAAG,IAAIT,MAAM,CAACC,IAAI,CAACJ,KAAK,CAAC,EAAE;QAClC,MAAMa,IAAI,GAAGb,KAAK,CAACY,GAAG,CAAC;QACvB,MAAME,WAAW,GAAG,GAAGH,QAAQ,IAAIC,GAAG,EAAE;QAExC,IAAIC,IAAI,CAACd,IAAI,KAAK,QAAQ,IAAIc,IAAI,CAACX,UAAU,EAAE;UAC3CG,QAAQ,CAACU,IAAI,CAAC;YACVhB,IAAI,EAAE,OAAO;YACbU,KAAK,EAAEI,IAAI,CAACG,EAAE,EAAEP,KAAK,IAAIG,GAAG;YAC5BP,QAAQ,EAAE,IAAI,CAACC,8BAA8B,CAACO,IAAI,CAACX,UAAU,EAAE,GAAGY,WAAW,aAAa;UAC9F,CAAC,CAAC;QACN,CAAC,MAAM;UACHT,QAAQ,CAACU,IAAI,CAAC;YACVhB,IAAI,EAAE,SAAS;YACfkB,KAAK,EAAEH;UACX,CAAC,CAAC;QACN;MACJ;MACA,OAAOT,QAAQ;IACnB;EACJ;EAAC,IAAAa,SAAA;IAAAC,UAAA;EAAA;EAAAD,SAAA,CAAA1B,sBAAA,GAAAA,sBAAA;EAAA,OAAA0B,SAAA;AAAA","ignoreList":[]}
@@ -21,6 +21,7 @@ declare module "nz/co/siliconst/ui5/metaui/core/DefaultLayoutGenerator" {
21
21
  * @returns boolean True if a layout was synthesized, false if it already existed or was empty.
22
22
  */
23
23
  static ensureLayout(schema: ISchema): boolean;
24
+ private static generateElementsFromProperties;
24
25
  }
25
26
  }
26
27
  //# sourceMappingURL=DefaultLayoutGenerator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DefaultLayoutGenerator.d.ts","sourceRoot":"../../../../../../../..","sources":["src/nz/co/siliconst/ui5/metaui/core/DefaultLayoutGenerator.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,wDAAwD,CAAC;IACxE;;;OAGG;IAEH,OAAO,EAAE,OAAO,EAAkB,MAAM,+CAA+C,CAAC;IAExF;;;;;;;;;OASG;IACH,MAAa,sBAAsB;QAC/B;;;;WAIG;eACW,YAAY,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO;KAsCvD;CAEA"}
1
+ {"version":3,"file":"DefaultLayoutGenerator.d.ts","sourceRoot":"../../../../../../../..","sources":["src/nz/co/siliconst/ui5/metaui/core/DefaultLayoutGenerator.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,wDAAwD,CAAC;IACxE;;;OAGG;IAEH,OAAO,EAAE,OAAO,EAAkB,MAAM,+CAA+C,CAAC;IAExF;;;;;;;;;OASG;IACH,MAAa,sBAAsB;QAC/B;;;;WAIG;eACW,YAAY,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO;QAkCpD,OAAO,CAAC,MAAM,CAAC,8BAA8B;KAqBhD;CAEA"}
@@ -1,2 +1,2 @@
1
- sap.ui.define([],function(){"use strict";class e{static ensureLayout(e){if(e.uiLayout&&Array.isArray(e.uiLayout)&&e.uiLayout.length>0){return false}const t=e.type==="array";const r=t?e.items?.properties:e.properties;if(!r||Object.keys(r).length===0){return false}const u=[];for(const e of Object.keys(r)){u.push({type:"Control",scope:`#/properties/${e}`})}if(t){e.uiLayout=u}else{e.uiLayout=[{type:"Group",label:e.title,elements:u}]}return true}}var t={__esModule:true};t.DefaultLayoutGenerator=e;return t});
1
+ sap.ui.define([],function(){"use strict";class e{static ensureLayout(e){if(e.uiLayout&&Array.isArray(e.uiLayout)&&e.uiLayout.length>0){return false}const t=e.type==="array";const r=t?e.items?.properties:e.properties;if(!r||Object.keys(r).length===0){return false}const s=this.generateElementsFromProperties(r,"#/properties");if(t){e.uiLayout=s.filter(e=>e.type==="Control")}else{e.uiLayout=[{type:"Group",label:e.title,elements:s}]}return true}static generateElementsFromProperties(e,t){const r=[];for(const s of Object.keys(e)){const o=e[s];const i=`${t}/${s}`;if(o.type==="object"&&o.properties){r.push({type:"Group",label:o.ui?.label||s,elements:this.generateElementsFromProperties(o.properties,`${i}/properties`)})}else{r.push({type:"Control",scope:i})}}return r}}var t={__esModule:true};t.DefaultLayoutGenerator=e;return t});
2
2
  //# sourceMappingURL=DefaultLayoutGenerator.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DefaultLayoutGenerator.js","names":["DefaultLayoutGenerator","ensureLayout","schema","uiLayout","Array","isArray","length","type","props","items","properties","Object","keys","elements","key","push","scope","label","title","__exports","__esModule"],"sources":["DefaultLayoutGenerator.ts"],"sourcesContent":["/**\n * @file DefaultLayoutGenerator.ts\n * @description Automatically synthesizes a default UI layout for schemas that lack an explicit mapping.\n */\n\nimport { ISchema, ILayoutElement } from \"../interfaces/ISchema\";\n\n/**\n * Encapsulates the logic to dynamically build a safe, default layout orchestration\n * when the developer or backend fails to provide an explicit `uiLayout`.\n * \n * By elevating this into a dedicated utility, we avoid polluting layout engines\n * (like FormLayout or TableLayout) with structural inference responsibilities.\n * \n * @namespace nz.co.siliconst.ui5.metaui.core\n * @public\n */\nexport class DefaultLayoutGenerator {\n /**\n * Inspects a schema. If it has properties but no `uiLayout`, it synthesizes a default.\n * @param schema The ISchema dictionary.\n * @returns boolean True if a layout was synthesized, false if it already existed or was empty.\n */\n public static ensureLayout(schema: ISchema): boolean {\n // If it already has a valid array, do nothing\n if (schema.uiLayout && Array.isArray(schema.uiLayout) && schema.uiLayout.length > 0) {\n return false;\n }\n\n const isArray = schema.type === \"array\";\n const props = isArray ? schema.items?.properties : schema.properties;\n\n if (!props || Object.keys(props).length === 0) {\n return false; // Nothing to map\n }\n\n const elements: ILayoutElement[] = [];\n\n for (const key of Object.keys(props)) {\n elements.push({\n type: \"Control\",\n scope: `#/properties/${key}`\n });\n }\n\n if (isArray) {\n // Table layouts expect an array of flat Controls at the root uiLayout\n schema.uiLayout = elements;\n } else {\n // Form layouts expect a grouped structure\n schema.uiLayout = [\n {\n type: \"Group\",\n label: schema.title,\n elements: elements\n }\n ];\n }\n\n return true;\n }\n}\n"],"mappings":"yCAiBO,MAAMA,EAMT,mBAAcC,CAAaC,GAEvB,GAAIA,EAAOC,UAAYC,MAAMC,QAAQH,EAAOC,WAAaD,EAAOC,SAASG,OAAS,EAAG,CACjF,OAAO,KACX,CAEA,MAAMD,EAAUH,EAAOK,OAAS,QAChC,MAAMC,EAAQH,EAAUH,EAAOO,OAAOC,WAAaR,EAAOQ,WAE1D,IAAKF,GAASG,OAAOC,KAAKJ,GAAOF,SAAW,EAAG,CAC3C,OAAO,KACX,CAEA,MAAMO,EAA6B,GAEnC,IAAK,MAAMC,KAAOH,OAAOC,KAAKJ,GAAQ,CAClCK,EAASE,KAAK,CACVR,KAAM,UACNS,MAAO,gBAAgBF,KAE/B,CAEA,GAAIT,EAAS,CAETH,EAAOC,SAAWU,CACtB,KAAO,CAEHX,EAAOC,SAAW,CACd,CACII,KAAM,QACNU,MAAOf,EAAOgB,MACdL,SAAUA,GAGtB,CAEA,OAAO,IACX,EACH,IAAAM,EAAA,CAAAC,WAAA,MAAAD,EAAAnB,yBAAA,OAAAmB,CAAA","ignoreList":[]}
1
+ {"version":3,"file":"DefaultLayoutGenerator.js","names":["DefaultLayoutGenerator","ensureLayout","schema","uiLayout","Array","isArray","length","type","props","items","properties","Object","keys","elements","this","generateElementsFromProperties","filter","e","label","title","basePath","key","prop","currentPath","push","ui","scope","__exports","__esModule"],"sources":["DefaultLayoutGenerator.ts"],"sourcesContent":["/**\n * @file DefaultLayoutGenerator.ts\n * @description Automatically synthesizes a default UI layout for schemas that lack an explicit mapping.\n */\n\nimport { ISchema, ILayoutElement } from \"../interfaces/ISchema\";\n\n/**\n * Encapsulates the logic to dynamically build a safe, default layout orchestration\n * when the developer or backend fails to provide an explicit `uiLayout`.\n * \n * By elevating this into a dedicated utility, we avoid polluting layout engines\n * (like FormLayout or TableLayout) with structural inference responsibilities.\n * \n * @namespace nz.co.siliconst.ui5.metaui.core\n * @public\n */\nexport class DefaultLayoutGenerator {\n /**\n * Inspects a schema. If it has properties but no `uiLayout`, it synthesizes a default.\n * @param schema The ISchema dictionary.\n * @returns boolean True if a layout was synthesized, false if it already existed or was empty.\n */\n public static ensureLayout(schema: ISchema): boolean {\n // If it already has a valid array, do nothing\n if (schema.uiLayout && Array.isArray(schema.uiLayout) && schema.uiLayout.length > 0) {\n return false;\n }\n\n const isArray = schema.type === \"array\";\n const props = isArray ? schema.items?.properties : schema.properties;\n\n if (!props || Object.keys(props).length === 0) {\n return false; // Nothing to map\n }\n\n const elements = this.generateElementsFromProperties(props, \"#/properties\");\n\n if (isArray) {\n // Table layouts expect an array of flat Controls at the root uiLayout\n // For tables, we flatten the deep elements or just render the root level\n // To keep it safe, we'll just use the flat elements for tables\n schema.uiLayout = elements.filter(e => e.type === \"Control\");\n } else {\n // Form layouts expect a grouped structure\n schema.uiLayout = [\n {\n type: \"Group\",\n label: schema.title,\n elements: elements\n }\n ];\n }\n\n return true;\n }\n\n private static generateElementsFromProperties(props: any, basePath: string): ILayoutElement[] {\n const elements: ILayoutElement[] = [];\n for (const key of Object.keys(props)) {\n const prop = props[key];\n const currentPath = `${basePath}/${key}`;\n\n if (prop.type === \"object\" && prop.properties) {\n elements.push({\n type: \"Group\",\n label: prop.ui?.label || key,\n elements: this.generateElementsFromProperties(prop.properties, `${currentPath}/properties`)\n });\n } else {\n elements.push({\n type: \"Control\",\n scope: currentPath\n });\n }\n }\n return elements;\n }\n}\n"],"mappings":"yCAiBO,MAAMA,EAMT,mBAAcC,CAAaC,GAEvB,GAAIA,EAAOC,UAAYC,MAAMC,QAAQH,EAAOC,WAAaD,EAAOC,SAASG,OAAS,EAAG,CACjF,OAAO,KACX,CAEA,MAAMD,EAAUH,EAAOK,OAAS,QAChC,MAAMC,EAAQH,EAAUH,EAAOO,OAAOC,WAAaR,EAAOQ,WAE1D,IAAKF,GAASG,OAAOC,KAAKJ,GAAOF,SAAW,EAAG,CAC3C,OAAO,KACX,CAEA,MAAMO,EAAWC,KAAKC,+BAA+BP,EAAO,gBAE5D,GAAIH,EAAS,CAITH,EAAOC,SAAWU,EAASG,OAAOC,GAAKA,EAAEV,OAAS,UACtD,KAAO,CAEHL,EAAOC,SAAW,CACd,CACII,KAAM,QACNW,MAAOhB,EAAOiB,MACdN,SAAUA,GAGtB,CAEA,OAAO,IACX,CAEA,qCAAeE,CAA+BP,EAAYY,GACtD,MAAMP,EAA6B,GACnC,IAAK,MAAMQ,KAAOV,OAAOC,KAAKJ,GAAQ,CAClC,MAAMc,EAAOd,EAAMa,GACnB,MAAME,EAAc,GAAGH,KAAYC,IAEnC,GAAIC,EAAKf,OAAS,UAAYe,EAAKZ,WAAY,CAC3CG,EAASW,KAAK,CACVjB,KAAM,QACNW,MAAOI,EAAKG,IAAIP,OAASG,EACzBR,SAAUC,KAAKC,+BAA+BO,EAAKZ,WAAY,GAAGa,iBAE1E,KAAO,CACHV,EAASW,KAAK,CACVjB,KAAM,UACNmB,MAAOH,GAEf,CACJ,CACA,OAAOV,CACX,EACH,IAAAc,EAAA,CAAAC,WAAA,MAAAD,EAAA3B,yBAAA,OAAA2B,CAAA","ignoreList":[]}
@@ -34,18 +34,13 @@ export class DefaultLayoutGenerator {
34
34
  return false; // Nothing to map
35
35
  }
36
36
 
37
- const elements: ILayoutElement[] = [];
38
-
39
- for (const key of Object.keys(props)) {
40
- elements.push({
41
- type: "Control",
42
- scope: `#/properties/${key}`
43
- });
44
- }
37
+ const elements = this.generateElementsFromProperties(props, "#/properties");
45
38
 
46
39
  if (isArray) {
47
40
  // Table layouts expect an array of flat Controls at the root uiLayout
48
- schema.uiLayout = elements;
41
+ // For tables, we flatten the deep elements or just render the root level
42
+ // To keep it safe, we'll just use the flat elements for tables
43
+ schema.uiLayout = elements.filter(e => e.type === "Control");
49
44
  } else {
50
45
  // Form layouts expect a grouped structure
51
46
  schema.uiLayout = [
@@ -59,4 +54,26 @@ export class DefaultLayoutGenerator {
59
54
 
60
55
  return true;
61
56
  }
57
+
58
+ private static generateElementsFromProperties(props: any, basePath: string): ILayoutElement[] {
59
+ const elements: ILayoutElement[] = [];
60
+ for (const key of Object.keys(props)) {
61
+ const prop = props[key];
62
+ const currentPath = `${basePath}/${key}`;
63
+
64
+ if (prop.type === "object" && prop.properties) {
65
+ elements.push({
66
+ type: "Group",
67
+ label: prop.ui?.label || key,
68
+ elements: this.generateElementsFromProperties(prop.properties, `${currentPath}/properties`)
69
+ });
70
+ } else {
71
+ elements.push({
72
+ type: "Control",
73
+ scope: currentPath
74
+ });
75
+ }
76
+ }
77
+ return elements;
78
+ }
62
79
  }
@@ -30,10 +30,10 @@ sap.ui.define(["./ConditionEngine", "./PluginRegistry", "sap/m/Text", "../utils/
30
30
 
31
31
  /** Deterministic scope ID injected by the host control to prevent clone collisions. */
32
32
 
33
- /** Tracks whether the entire engine is running in Read-Only Display mode. */
34
- isDisplayMode = false;
35
- constructor(displayMode = false) {
36
- this.isDisplayMode = displayMode;
33
+ /** Tracks whether the entire engine is running in Editable mode. */
34
+ isEditable = true;
35
+ constructor(editable = true) {
36
+ this.isEditable = editable;
37
37
  }
38
38
 
39
39
  /**
@@ -90,7 +90,7 @@ sap.ui.define(["./ConditionEngine", "./PluginRegistry", "sap/m/Text", "../utils/
90
90
  generateField(fieldMeta, bindingPath, modelName, isTemplate = false) {
91
91
  try {
92
92
  const plugin = PluginRegistry.getInstance().getPlugin(fieldMeta.type || "string", fieldMeta.ui?.widget);
93
- plugin.setDisplayMode(this.isDisplayMode);
93
+ plugin.setEditable(this.isEditable);
94
94
  if (!isTemplate) {
95
95
  this.activePlugins.push({
96
96
  plugin,
@@ -1 +1 @@
1
- {"version":3,"file":"Engine-dbg.js","names":["ConditionEngine","___ConditionEngine","PluginRegistry","___PluginRegistry","Logger","___utils_Logger","DefaultLayoutGenerator","___DefaultLayoutGenerator","Engine","conditionEngine","activePlugins","isDisplayMode","constructor","displayMode","build","schema","model","modelName","onSubmit","engineScopeId","onChange","activeModel","isValid","fieldKey","errorMessage","controlId","handleEvent","ensureLayout","warn","layoutStrategy","type","layoutManager","layoutRegistry","getStrict","render","error","msg","message","showErrorPopup","Text","text","generateField","fieldMeta","bindingPath","isTemplate","plugin","getInstance","getPlugin","ui","widget","setDisplayMode","push","path","scopeId","undefined","control","registerPlugin","generateLayout","validateAll","errors","item","result","validate","replace","name","destroy","messageManager","Messaging","existingMessages","getMessageModel","getData","messagesToRemove","targetPath","matched","filter","getTarget","getMessageProcessor","getId","length","removeMessages","__exports","__esModule"],"sources":["Engine.ts"],"sourcesContent":["/**\n * @file Engine.ts\n * @description The central orchestrator that routes data between the Layout Factory and Plugin Registry (v2).\n */\n\nimport { ISchema, IPropertyMetadata } from \"../interfaces/ISchema\";\nimport { ILayoutManager } from \"../interfaces/ILayoutManager\";\nimport { IPlugin, IPluginValidationResult } from \"../interfaces/IPlugin\";\nimport { ConditionEngine } from \"./ConditionEngine\";\nimport { PluginRegistry } from \"./PluginRegistry\";\nimport Control from \"sap/ui/core/Control\";\nimport VBox from \"sap/m/VBox\";\nimport Text from \"sap/m/Text\";\nimport { Registry } from \"./Registry\";\nimport { Logger } from \"../utils/Logger\";\nimport { DefaultLayoutGenerator } from \"./DefaultLayoutGenerator\";\nimport Core from \"sap/ui/core/Core\";\nimport Messaging from \"sap/ui/core/Messaging\";\n\n/**\n * The Engine is responsible for translating a normalized schema into a physical UI5 layout.\n * It delegates layout generation to the configured `LayoutManager` and field generation to the `PluginRegistry`.\n * It is NOT a God Class; it strictly routes execution flow and tracks active plugins for validation.\n * It embodies the \"Plugin-First Philosophy\" by routing all complex field and layout rendering\n * through discrete, decoupled plugins rather than handling native overrides.\n * \n * @namespace nz.co.siliconst.ui5.metaui.core\n * @public\n */\nexport class Engine {\n /** Global registry of all available layout strategies (e.g. Form, Table, Wizard). */\n public static layoutRegistry: Registry<ILayoutManager>;\n /** Handles dynamic conditional logic across the active form. */\n private conditionEngine: ConditionEngine | null = null;\n \n /** Array of all instantiated plugins generated during the current build. */\n private activePlugins: { plugin: IPlugin, path: string }[] = [];\n\n /** Deterministic scope ID injected by the host control to prevent clone collisions. */\n public engineScopeId?: string;\n \n private activeModel?: sap.ui.model.Model;\n \n /** Tracks whether the entire engine is running in Read-Only Display mode. */\n public readonly isDisplayMode: boolean = false;\n\n constructor(displayMode: boolean = false) {\n this.isDisplayMode = displayMode;\n }\n \n /**\n * Bootstraps the layout generation process by resolving the correct layout strategy.\n * \n * @param schema The normalized JSON schema representing the view.\n * @param model The active StateManager JSONModel instance.\n * @param modelName The UI5 model alias used for isolation.\n * @param onSubmit Callback fired when form is submitted.\n * @param engineScopeId Deterministic scope ID for this engine instance.\n * @param onChange Callback fired when field values change.\n * @returns The generated root UI5 Control container.\n */\n public build(schema: ISchema, model: sap.ui.model.Model, modelName: string = \"meta\", onSubmit?: () => void, engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.conditionEngine = new ConditionEngine(schema);\n this.activePlugins = [];\n this.activeModel = model;\n this.engineScopeId = engineScopeId;\n this.onChange = (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => {\n if (this.conditionEngine && fieldKey) {\n this.conditionEngine.handleEvent(fieldKey, isValid);\n }\n if (onChange) {\n onChange(isValid, fieldKey, errorMessage, controlId);\n }\n };\n \n try {\n // Intercept and synthesize a default layout if the developer/backend failed to provide one\n if (DefaultLayoutGenerator.ensureLayout(schema)) {\n Logger.warn(\"[MetaUI Engine] Missing 'uiLayout' array in schema. Synthesized a default layout mapping to prevent a blank render.\");\n }\n\n const layoutStrategy = schema.layoutStrategy || (schema.type === \"array\" ? \"table\" : \"form\");\n const layoutManager = Engine.layoutRegistry.getStrict(layoutStrategy);\n \n return layoutManager.render(schema, modelName, this, onSubmit);\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(\"[MetaUI Engine] Critical error during layout generation\", msg);\n Logger.showErrorPopup(`Engine failed to generate the layout.\\n\\nDetails: ${msg}`);\n return new Text({ text: \"Critical Layout Error\" });\n }\n }\n\n /**\n * Instantiates the correct plugin for a specific field based on type and widget hints,\n * and tracks the plugin for global validation.\n * \n * @param fieldMeta The metadata schema specific to the field.\n * @param bindingPath The JSON path representing the field within the payload.\n * @param modelName The UI5 JSONModel name used for data binding.\n * @returns The generated UI5 Control for the field.\n */\n public generateField(fieldMeta: IPropertyMetadata, bindingPath: string, modelName: string, isTemplate: boolean = false): Control {\n try {\n const plugin = PluginRegistry.getInstance().getPlugin(fieldMeta.type || \"string\", fieldMeta.ui?.widget);\n plugin.setDisplayMode(this.isDisplayMode);\n \n if (!isTemplate) {\n this.activePlugins.push({ plugin, path: bindingPath });\n }\n const scopeId = isTemplate ? undefined : this.engineScopeId;\n const control = plugin.render(fieldMeta, bindingPath, modelName, scopeId, this.onChange);\n \n if (this.conditionEngine) {\n this.conditionEngine.registerPlugin(bindingPath, plugin);\n }\n \n return control;\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI Engine] Failed to generate field at ${bindingPath}`, msg);\n Logger.showErrorPopup(`Failed to generate field '${bindingPath}'.\\n\\nDetails: ${msg}`);\n return new Text({ text: `[Error generating field ${bindingPath}]` });\n }\n }\n\n /**\n * Generates a sub-layout (like an embedded table or nested form) without \n * destroying the current Engine state or Condition tracking.\n * \n * @param schema The normalized JSON schema representing the view.\n * @param modelName The UI5 JSONModel name used for data binding (defaults to \"meta\").\n * @param bindingPath Optional path to bind the sub-layout to a specific array/object property.\n * @returns The generated root UI5 Control container.\n */\n public generateLayout(schema: ISchema, modelName: string, bindingPath?: string): Control {\n try {\n const layoutStrategy = schema.layoutStrategy || (schema.type === \"array\" ? \"table\" : \"form\");\n const layoutManager = Engine.layoutRegistry.getStrict(layoutStrategy);\n return layoutManager.render(schema, modelName, this, undefined, bindingPath);\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI Engine] Critical error generating sub-layout for ${bindingPath}`, msg);\n Logger.showErrorPopup(`Engine failed to generate a sub-layout.\\n\\nDetails: ${msg}`);\n return new Text({ text: \"Critical Sub-Layout Error\" });\n }\n }\n\n /**\n * Iterates through all active plugins and triggers their internal validation pipelines.\n * \n * @returns {IPluginValidationResult[]} Array of validation error objects. Empty array if valid.\n */\n public validateAll(): IPluginValidationResult[] {\n const errors: IPluginValidationResult[] = [];\n for (const item of this.activePlugins) {\n const result = item.plugin.validate();\n if (!result.isValid) {\n // Ensure the path is bound to the error so GeneratorHost knows where to target it\n result.fieldKey = result.fieldKey || item.path.replace(/^\\//, \"\");\n errors.push(result);\n // Add console log to find which plugin fails silently\n Logger.error(\"[MetaUI Validation] Plugin failed validation silently:\", item.path || item.plugin.constructor.name);\n }\n }\n return errors;\n }\n\n /**\n * Cleans up internal state and destroys the condition engine to prevent memory leaks.\n */\n public destroy(): void {\n if (this.conditionEngine) {\n this.conditionEngine.destroy();\n this.conditionEngine = null;\n }\n \n // ------------------------------------------------------------------------\n // Ghost Error Prevention\n // Flush MessageManager for active plugins before destroying their controls\n // ------------------------------------------------------------------------\n const messageManager = Messaging;\n const existingMessages = messageManager.getMessageModel().getData();\n const messagesToRemove: any[] = [];\n \n for (const item of this.activePlugins) {\n if (this.activeModel) {\n const targetPath = `/${item.path.replace(/^\\//, \"\")}`;\n const matched = existingMessages.filter((msg: any) => \n msg.getTarget() === targetPath && msg.getMessageProcessor() && msg.getMessageProcessor().getId() === this.activeModel.getId()\n );\n messagesToRemove.push(...matched);\n }\n if (typeof item.plugin.destroy === \"function\") {\n item.plugin.destroy();\n }\n }\n \n if (messagesToRemove.length > 0) {\n messageManager.removeMessages(messagesToRemove);\n }\n \n this.activePlugins = [];\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"Engine-dbg.js","names":["ConditionEngine","___ConditionEngine","PluginRegistry","___PluginRegistry","Logger","___utils_Logger","DefaultLayoutGenerator","___DefaultLayoutGenerator","Engine","conditionEngine","activePlugins","isEditable","constructor","editable","build","schema","model","modelName","onSubmit","engineScopeId","onChange","activeModel","isValid","fieldKey","errorMessage","controlId","handleEvent","ensureLayout","warn","layoutStrategy","type","layoutManager","layoutRegistry","getStrict","render","error","msg","message","showErrorPopup","Text","text","generateField","fieldMeta","bindingPath","isTemplate","plugin","getInstance","getPlugin","ui","widget","setEditable","push","path","scopeId","undefined","control","registerPlugin","generateLayout","validateAll","errors","item","result","validate","replace","name","destroy","messageManager","Messaging","existingMessages","getMessageModel","getData","messagesToRemove","targetPath","matched","filter","getTarget","getMessageProcessor","getId","length","removeMessages","__exports","__esModule"],"sources":["Engine.ts"],"sourcesContent":["/**\n * @file Engine.ts\n * @description The central orchestrator that routes data between the Layout Factory and Plugin Registry (v2).\n */\n\nimport { ISchema, IPropertyMetadata } from \"../interfaces/ISchema\";\nimport { ILayoutManager } from \"../interfaces/ILayoutManager\";\nimport { IPlugin, IPluginValidationResult } from \"../interfaces/IPlugin\";\nimport { ConditionEngine } from \"./ConditionEngine\";\nimport { PluginRegistry } from \"./PluginRegistry\";\nimport Control from \"sap/ui/core/Control\";\nimport VBox from \"sap/m/VBox\";\nimport Text from \"sap/m/Text\";\nimport { Registry } from \"./Registry\";\nimport { Logger } from \"../utils/Logger\";\nimport { DefaultLayoutGenerator } from \"./DefaultLayoutGenerator\";\nimport Core from \"sap/ui/core/Core\";\nimport Messaging from \"sap/ui/core/Messaging\";\n\n/**\n * The Engine is responsible for translating a normalized schema into a physical UI5 layout.\n * It delegates layout generation to the configured `LayoutManager` and field generation to the `PluginRegistry`.\n * It is NOT a God Class; it strictly routes execution flow and tracks active plugins for validation.\n * It embodies the \"Plugin-First Philosophy\" by routing all complex field and layout rendering\n * through discrete, decoupled plugins rather than handling native overrides.\n * \n * @namespace nz.co.siliconst.ui5.metaui.core\n * @public\n */\nexport class Engine {\n /** Global registry of all available layout strategies (e.g. Form, Table, Wizard). */\n public static layoutRegistry: Registry<ILayoutManager>;\n /** Handles dynamic conditional logic across the active form. */\n private conditionEngine: ConditionEngine | null = null;\n \n /** Array of all instantiated plugins generated during the current build. */\n private activePlugins: { plugin: IPlugin, path: string }[] = [];\n\n /** Deterministic scope ID injected by the host control to prevent clone collisions. */\n public engineScopeId?: string;\n \n private activeModel?: sap.ui.model.Model;\n \n /** Tracks whether the entire engine is running in Editable mode. */\n public readonly isEditable: boolean = true;\n\n constructor(editable: boolean = true) {\n this.isEditable = editable;\n }\n \n /**\n * Bootstraps the layout generation process by resolving the correct layout strategy.\n * \n * @param schema The normalized JSON schema representing the view.\n * @param model The active StateManager JSONModel instance.\n * @param modelName The UI5 model alias used for isolation.\n * @param onSubmit Callback fired when form is submitted.\n * @param engineScopeId Deterministic scope ID for this engine instance.\n * @param onChange Callback fired when field values change.\n * @returns The generated root UI5 Control container.\n */\n public build(schema: ISchema, model: sap.ui.model.Model, modelName: string = \"meta\", onSubmit?: () => void, engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.conditionEngine = new ConditionEngine(schema);\n this.activePlugins = [];\n this.activeModel = model;\n this.engineScopeId = engineScopeId;\n this.onChange = (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => {\n if (this.conditionEngine && fieldKey) {\n this.conditionEngine.handleEvent(fieldKey, isValid);\n }\n if (onChange) {\n onChange(isValid, fieldKey, errorMessage, controlId);\n }\n };\n \n try {\n // Intercept and synthesize a default layout if the developer/backend failed to provide one\n if (DefaultLayoutGenerator.ensureLayout(schema)) {\n Logger.warn(\"[MetaUI Engine] Missing 'uiLayout' array in schema. Synthesized a default layout mapping to prevent a blank render.\");\n }\n\n const layoutStrategy = schema.layoutStrategy || (schema.type === \"array\" ? \"table\" : \"form\");\n const layoutManager = Engine.layoutRegistry.getStrict(layoutStrategy);\n \n return layoutManager.render(schema, modelName, this, onSubmit);\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(\"[MetaUI Engine] Critical error during layout generation\", msg);\n Logger.showErrorPopup(`Engine failed to generate the layout.\\n\\nDetails: ${msg}`);\n return new Text({ text: \"Critical Layout Error\" });\n }\n }\n\n /**\n * Instantiates the correct plugin for a specific field based on type and widget hints,\n * and tracks the plugin for global validation.\n * \n * @param fieldMeta The metadata schema specific to the field.\n * @param bindingPath The JSON path representing the field within the payload.\n * @param modelName The UI5 JSONModel name used for data binding.\n * @returns The generated UI5 Control for the field.\n */\n public generateField(fieldMeta: IPropertyMetadata, bindingPath: string, modelName: string, isTemplate: boolean = false): Control {\n try {\n const plugin = PluginRegistry.getInstance().getPlugin(fieldMeta.type || \"string\", fieldMeta.ui?.widget);\n plugin.setEditable(this.isEditable);\n \n if (!isTemplate) {\n this.activePlugins.push({ plugin, path: bindingPath });\n }\n const scopeId = isTemplate ? undefined : this.engineScopeId;\n const control = plugin.render(fieldMeta, bindingPath, modelName, scopeId, this.onChange);\n \n if (this.conditionEngine) {\n this.conditionEngine.registerPlugin(bindingPath, plugin);\n }\n \n return control;\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI Engine] Failed to generate field at ${bindingPath}`, msg);\n Logger.showErrorPopup(`Failed to generate field '${bindingPath}'.\\n\\nDetails: ${msg}`);\n return new Text({ text: `[Error generating field ${bindingPath}]` });\n }\n }\n\n /**\n * Generates a sub-layout (like an embedded table or nested form) without \n * destroying the current Engine state or Condition tracking.\n * \n * @param schema The normalized JSON schema representing the view.\n * @param modelName The UI5 JSONModel name used for data binding (defaults to \"meta\").\n * @param bindingPath Optional path to bind the sub-layout to a specific array/object property.\n * @returns The generated root UI5 Control container.\n */\n public generateLayout(schema: ISchema, modelName: string, bindingPath?: string): Control {\n try {\n const layoutStrategy = schema.layoutStrategy || (schema.type === \"array\" ? \"table\" : \"form\");\n const layoutManager = Engine.layoutRegistry.getStrict(layoutStrategy);\n return layoutManager.render(schema, modelName, this, undefined, bindingPath);\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI Engine] Critical error generating sub-layout for ${bindingPath}`, msg);\n Logger.showErrorPopup(`Engine failed to generate a sub-layout.\\n\\nDetails: ${msg}`);\n return new Text({ text: \"Critical Sub-Layout Error\" });\n }\n }\n\n /**\n * Iterates through all active plugins and triggers their internal validation pipelines.\n * \n * @returns {IPluginValidationResult[]} Array of validation error objects. Empty array if valid.\n */\n public validateAll(): IPluginValidationResult[] {\n const errors: IPluginValidationResult[] = [];\n for (const item of this.activePlugins) {\n const result = item.plugin.validate();\n if (!result.isValid) {\n // Ensure the path is bound to the error so GeneratorHost knows where to target it\n result.fieldKey = result.fieldKey || item.path.replace(/^\\//, \"\");\n errors.push(result);\n // Add console log to find which plugin fails silently\n Logger.error(\"[MetaUI Validation] Plugin failed validation silently:\", item.path || item.plugin.constructor.name);\n }\n }\n return errors;\n }\n\n /**\n * Cleans up internal state and destroys the condition engine to prevent memory leaks.\n */\n public destroy(): void {\n if (this.conditionEngine) {\n this.conditionEngine.destroy();\n this.conditionEngine = null;\n }\n \n // ------------------------------------------------------------------------\n // Ghost Error Prevention\n // Flush MessageManager for active plugins before destroying their controls\n // ------------------------------------------------------------------------\n const messageManager = Messaging;\n const existingMessages = messageManager.getMessageModel().getData();\n const messagesToRemove: any[] = [];\n \n for (const item of this.activePlugins) {\n if (this.activeModel) {\n const targetPath = `/${item.path.replace(/^\\//, \"\")}`;\n const matched = existingMessages.filter((msg: any) => \n msg.getTarget() === targetPath && msg.getMessageProcessor() && msg.getMessageProcessor().getId() === this.activeModel.getId()\n );\n messagesToRemove.push(...matched);\n }\n if (typeof item.plugin.destroy === \"function\") {\n item.plugin.destroy();\n }\n }\n \n if (messagesToRemove.length > 0) {\n messageManager.removeMessages(messagesToRemove);\n }\n \n this.activePlugins = [];\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -28,9 +28,9 @@ declare module "nz/co/siliconst/ui5/metaui/core/Engine" {
28
28
  /** Deterministic scope ID injected by the host control to prevent clone collisions. */
29
29
  engineScopeId?: string;
30
30
  private activeModel?;
31
- /** Tracks whether the entire engine is running in Read-Only Display mode. */
32
- readonly isDisplayMode: boolean;
33
- constructor(displayMode?: boolean);
31
+ /** Tracks whether the entire engine is running in Editable mode. */
32
+ readonly isEditable: boolean;
33
+ constructor(editable?: boolean);
34
34
  /**
35
35
  * Bootstraps the layout generation process by resolving the correct layout strategy.
36
36
  *
@@ -1 +1 @@
1
- {"version":3,"file":"Engine.d.ts","sourceRoot":"../../../../../../../..","sources":["src/nz/co/siliconst/ui5/metaui/core/Engine.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,wCAAwC,CAAC;IACxD;;;OAGG;IAEH,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,+CAA+C,CAAC;IAC3F,OAAO,EAAE,cAAc,EAAE,MAAM,sDAAsD,CAAC;IACtF,OAAO,EAAW,uBAAuB,EAAE,MAAM,+CAA+C,CAAC;IAGjG,OAAO,OAAO,MAAM,qBAAqB,CAAC;IAG1C,OAAO,EAAE,QAAQ,EAAE,MAAM,0CAA0C,CAAC;IAMpE;;;;;;;;;OASG;IACH,MAAa,MAAM;QACf,qFAAqF;QACrF,OAAc,cAAc,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC;QACvD,gEAAgE;QAChE,OAAO,CAAC,eAAe,CAAgC;QAEvD,4EAA4E;QAC5E,OAAO,CAAC,aAAa,CAA2C;QAEhE,uFAAuF;QAChF,aAAa,CAAC,EAAE,MAAM,CAAC;QAE9B,OAAO,CAAC,WAAW,CAAC,CAAqB;QAEzC,6EAA6E;QAC7E,SAAgB,aAAa,EAAE,OAAO,CAAS;oBAEnC,WAAW,GAAE,OAAe;QAIxC;;;;;;;;;;WAUG;QACI,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,SAAS,GAAE,MAAe,EAAE,QAAQ,CAAC,EAAE,MAAM,IAAI,EAAE,aAAa,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO;QAgCjP;;;;;;;;WAQG;QACI,aAAa,CAAC,SAAS,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,GAAE,OAAe,GAAG,OAAO;QAwBhI;;;;;;;;WAQG;QACI,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO;QAaxF;;;;WAIG;QACI,WAAW,IAAI,uBAAuB,EAAE;QAe/C;;WAEG;QACI,OAAO,IAAI,IAAI;KAiCzB;CAEA"}
1
+ {"version":3,"file":"Engine.d.ts","sourceRoot":"../../../../../../../..","sources":["src/nz/co/siliconst/ui5/metaui/core/Engine.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,wCAAwC,CAAC;IACxD;;;OAGG;IAEH,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,+CAA+C,CAAC;IAC3F,OAAO,EAAE,cAAc,EAAE,MAAM,sDAAsD,CAAC;IACtF,OAAO,EAAW,uBAAuB,EAAE,MAAM,+CAA+C,CAAC;IAGjG,OAAO,OAAO,MAAM,qBAAqB,CAAC;IAG1C,OAAO,EAAE,QAAQ,EAAE,MAAM,0CAA0C,CAAC;IAMpE;;;;;;;;;OASG;IACH,MAAa,MAAM;QACf,qFAAqF;QACrF,OAAc,cAAc,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC;QACvD,gEAAgE;QAChE,OAAO,CAAC,eAAe,CAAgC;QAEvD,4EAA4E;QAC5E,OAAO,CAAC,aAAa,CAA2C;QAEhE,uFAAuF;QAChF,aAAa,CAAC,EAAE,MAAM,CAAC;QAE9B,OAAO,CAAC,WAAW,CAAC,CAAqB;QAEzC,oEAAoE;QACpE,SAAgB,UAAU,EAAE,OAAO,CAAQ;oBAE/B,QAAQ,GAAE,OAAc;QAIpC;;;;;;;;;;WAUG;QACI,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,SAAS,GAAE,MAAe,EAAE,QAAQ,CAAC,EAAE,MAAM,IAAI,EAAE,aAAa,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO;QAgCjP;;;;;;;;WAQG;QACI,aAAa,CAAC,SAAS,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,GAAE,OAAe,GAAG,OAAO;QAwBhI;;;;;;;;WAQG;QACI,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO;QAaxF;;;;WAIG;QACI,WAAW,IAAI,uBAAuB,EAAE;QAe/C;;WAEG;QACI,OAAO,IAAI,IAAI;KAiCzB;CAEA"}
@@ -1,2 +1,2 @@
1
- sap.ui.define(["./ConditionEngine","./PluginRegistry","sap/m/Text","../utils/Logger","./DefaultLayoutGenerator","sap/ui/core/Messaging"],function(e,t,n,i,r,o){"use strict";const s=e["ConditionEngine"];const a=t["PluginRegistry"];const g=i["Logger"];const l=r["DefaultLayoutGenerator"];class u{conditionEngine=null;activePlugins=[];isDisplayMode=false;constructor(e=false){this.isDisplayMode=e}build(e,t,i="meta",r,o,a){this.conditionEngine=new s(e);this.activePlugins=[];this.activeModel=t;this.engineScopeId=o;this.onChange=(e,t,n,i)=>{if(this.conditionEngine&&t){this.conditionEngine.handleEvent(t,e)}if(a){a(e,t,n,i)}};try{if(l.ensureLayout(e)){g.warn("[MetaUI Engine] Missing 'uiLayout' array in schema. Synthesized a default layout mapping to prevent a blank render.")}const t=e.layoutStrategy||(e.type==="array"?"table":"form");const n=u.layoutRegistry.getStrict(t);return n.render(e,i,this,r)}catch(e){const t=e.message;g.error("[MetaUI Engine] Critical error during layout generation",t);g.showErrorPopup(`Engine failed to generate the layout.\n\nDetails: ${t}`);return new n({text:"Critical Layout Error"})}}generateField(e,t,i,r=false){try{const n=a.getInstance().getPlugin(e.type||"string",e.ui?.widget);n.setDisplayMode(this.isDisplayMode);if(!r){this.activePlugins.push({plugin:n,path:t})}const o=r?undefined:this.engineScopeId;const s=n.render(e,t,i,o,this.onChange);if(this.conditionEngine){this.conditionEngine.registerPlugin(t,n)}return s}catch(e){const i=e.message;g.error(`[MetaUI Engine] Failed to generate field at ${t}`,i);g.showErrorPopup(`Failed to generate field '${t}'.\n\nDetails: ${i}`);return new n({text:`[Error generating field ${t}]`})}}generateLayout(e,t,i){try{const n=e.layoutStrategy||(e.type==="array"?"table":"form");const r=u.layoutRegistry.getStrict(n);return r.render(e,t,this,undefined,i)}catch(e){const t=e.message;g.error(`[MetaUI Engine] Critical error generating sub-layout for ${i}`,t);g.showErrorPopup(`Engine failed to generate a sub-layout.\n\nDetails: ${t}`);return new n({text:"Critical Sub-Layout Error"})}}validateAll(){const e=[];for(const t of this.activePlugins){const n=t.plugin.validate();if(!n.isValid){n.fieldKey=n.fieldKey||t.path.replace(/^\//,"");e.push(n);g.error("[MetaUI Validation] Plugin failed validation silently:",t.path||t.plugin.constructor.name)}}return e}destroy(){if(this.conditionEngine){this.conditionEngine.destroy();this.conditionEngine=null}const e=o;const t=e.getMessageModel().getData();const n=[];for(const e of this.activePlugins){if(this.activeModel){const i=`/${e.path.replace(/^\//,"")}`;const r=t.filter(e=>e.getTarget()===i&&e.getMessageProcessor()&&e.getMessageProcessor().getId()===this.activeModel.getId());n.push(...r)}if(typeof e.plugin.destroy==="function"){e.plugin.destroy()}}if(n.length>0){e.removeMessages(n)}this.activePlugins=[]}}var c={__esModule:true};c.Engine=u;return c});
1
+ sap.ui.define(["./ConditionEngine","./PluginRegistry","sap/m/Text","../utils/Logger","./DefaultLayoutGenerator","sap/ui/core/Messaging"],function(e,t,n,i,r,o){"use strict";const a=e["ConditionEngine"];const s=t["PluginRegistry"];const g=i["Logger"];const l=r["DefaultLayoutGenerator"];class u{conditionEngine=null;activePlugins=[];isEditable=true;constructor(e=true){this.isEditable=e}build(e,t,i="meta",r,o,s){this.conditionEngine=new a(e);this.activePlugins=[];this.activeModel=t;this.engineScopeId=o;this.onChange=(e,t,n,i)=>{if(this.conditionEngine&&t){this.conditionEngine.handleEvent(t,e)}if(s){s(e,t,n,i)}};try{if(l.ensureLayout(e)){g.warn("[MetaUI Engine] Missing 'uiLayout' array in schema. Synthesized a default layout mapping to prevent a blank render.")}const t=e.layoutStrategy||(e.type==="array"?"table":"form");const n=u.layoutRegistry.getStrict(t);return n.render(e,i,this,r)}catch(e){const t=e.message;g.error("[MetaUI Engine] Critical error during layout generation",t);g.showErrorPopup(`Engine failed to generate the layout.\n\nDetails: ${t}`);return new n({text:"Critical Layout Error"})}}generateField(e,t,i,r=false){try{const n=s.getInstance().getPlugin(e.type||"string",e.ui?.widget);n.setEditable(this.isEditable);if(!r){this.activePlugins.push({plugin:n,path:t})}const o=r?undefined:this.engineScopeId;const a=n.render(e,t,i,o,this.onChange);if(this.conditionEngine){this.conditionEngine.registerPlugin(t,n)}return a}catch(e){const i=e.message;g.error(`[MetaUI Engine] Failed to generate field at ${t}`,i);g.showErrorPopup(`Failed to generate field '${t}'.\n\nDetails: ${i}`);return new n({text:`[Error generating field ${t}]`})}}generateLayout(e,t,i){try{const n=e.layoutStrategy||(e.type==="array"?"table":"form");const r=u.layoutRegistry.getStrict(n);return r.render(e,t,this,undefined,i)}catch(e){const t=e.message;g.error(`[MetaUI Engine] Critical error generating sub-layout for ${i}`,t);g.showErrorPopup(`Engine failed to generate a sub-layout.\n\nDetails: ${t}`);return new n({text:"Critical Sub-Layout Error"})}}validateAll(){const e=[];for(const t of this.activePlugins){const n=t.plugin.validate();if(!n.isValid){n.fieldKey=n.fieldKey||t.path.replace(/^\//,"");e.push(n);g.error("[MetaUI Validation] Plugin failed validation silently:",t.path||t.plugin.constructor.name)}}return e}destroy(){if(this.conditionEngine){this.conditionEngine.destroy();this.conditionEngine=null}const e=o;const t=e.getMessageModel().getData();const n=[];for(const e of this.activePlugins){if(this.activeModel){const i=`/${e.path.replace(/^\//,"")}`;const r=t.filter(e=>e.getTarget()===i&&e.getMessageProcessor()&&e.getMessageProcessor().getId()===this.activeModel.getId());n.push(...r)}if(typeof e.plugin.destroy==="function"){e.plugin.destroy()}}if(n.length>0){e.removeMessages(n)}this.activePlugins=[]}}var c={__esModule:true};c.Engine=u;return c});
2
2
  //# sourceMappingURL=Engine.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Engine.js","names":["ConditionEngine","___ConditionEngine","PluginRegistry","___PluginRegistry","Logger","___utils_Logger","DefaultLayoutGenerator","___DefaultLayoutGenerator","Engine","conditionEngine","activePlugins","isDisplayMode","constructor","displayMode","this","build","schema","model","modelName","onSubmit","engineScopeId","onChange","activeModel","isValid","fieldKey","errorMessage","controlId","handleEvent","ensureLayout","warn","layoutStrategy","type","layoutManager","layoutRegistry","getStrict","render","error","msg","message","showErrorPopup","Text","text","generateField","fieldMeta","bindingPath","isTemplate","plugin","getInstance","getPlugin","ui","widget","setDisplayMode","push","path","scopeId","undefined","control","registerPlugin","generateLayout","validateAll","errors","item","result","validate","replace","name","destroy","messageManager","Messaging","existingMessages","getMessageModel","getData","messagesToRemove","targetPath","matched","filter","getTarget","getMessageProcessor","getId","length","removeMessages","__exports","__esModule"],"sources":["Engine.ts"],"sourcesContent":["/**\n * @file Engine.ts\n * @description The central orchestrator that routes data between the Layout Factory and Plugin Registry (v2).\n */\n\nimport { ISchema, IPropertyMetadata } from \"../interfaces/ISchema\";\nimport { ILayoutManager } from \"../interfaces/ILayoutManager\";\nimport { IPlugin, IPluginValidationResult } from \"../interfaces/IPlugin\";\nimport { ConditionEngine } from \"./ConditionEngine\";\nimport { PluginRegistry } from \"./PluginRegistry\";\nimport Control from \"sap/ui/core/Control\";\nimport VBox from \"sap/m/VBox\";\nimport Text from \"sap/m/Text\";\nimport { Registry } from \"./Registry\";\nimport { Logger } from \"../utils/Logger\";\nimport { DefaultLayoutGenerator } from \"./DefaultLayoutGenerator\";\nimport Core from \"sap/ui/core/Core\";\nimport Messaging from \"sap/ui/core/Messaging\";\n\n/**\n * The Engine is responsible for translating a normalized schema into a physical UI5 layout.\n * It delegates layout generation to the configured `LayoutManager` and field generation to the `PluginRegistry`.\n * It is NOT a God Class; it strictly routes execution flow and tracks active plugins for validation.\n * It embodies the \"Plugin-First Philosophy\" by routing all complex field and layout rendering\n * through discrete, decoupled plugins rather than handling native overrides.\n * \n * @namespace nz.co.siliconst.ui5.metaui.core\n * @public\n */\nexport class Engine {\n /** Global registry of all available layout strategies (e.g. Form, Table, Wizard). */\n public static layoutRegistry: Registry<ILayoutManager>;\n /** Handles dynamic conditional logic across the active form. */\n private conditionEngine: ConditionEngine | null = null;\n \n /** Array of all instantiated plugins generated during the current build. */\n private activePlugins: { plugin: IPlugin, path: string }[] = [];\n\n /** Deterministic scope ID injected by the host control to prevent clone collisions. */\n public engineScopeId?: string;\n \n private activeModel?: sap.ui.model.Model;\n \n /** Tracks whether the entire engine is running in Read-Only Display mode. */\n public readonly isDisplayMode: boolean = false;\n\n constructor(displayMode: boolean = false) {\n this.isDisplayMode = displayMode;\n }\n \n /**\n * Bootstraps the layout generation process by resolving the correct layout strategy.\n * \n * @param schema The normalized JSON schema representing the view.\n * @param model The active StateManager JSONModel instance.\n * @param modelName The UI5 model alias used for isolation.\n * @param onSubmit Callback fired when form is submitted.\n * @param engineScopeId Deterministic scope ID for this engine instance.\n * @param onChange Callback fired when field values change.\n * @returns The generated root UI5 Control container.\n */\n public build(schema: ISchema, model: sap.ui.model.Model, modelName: string = \"meta\", onSubmit?: () => void, engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.conditionEngine = new ConditionEngine(schema);\n this.activePlugins = [];\n this.activeModel = model;\n this.engineScopeId = engineScopeId;\n this.onChange = (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => {\n if (this.conditionEngine && fieldKey) {\n this.conditionEngine.handleEvent(fieldKey, isValid);\n }\n if (onChange) {\n onChange(isValid, fieldKey, errorMessage, controlId);\n }\n };\n \n try {\n // Intercept and synthesize a default layout if the developer/backend failed to provide one\n if (DefaultLayoutGenerator.ensureLayout(schema)) {\n Logger.warn(\"[MetaUI Engine] Missing 'uiLayout' array in schema. Synthesized a default layout mapping to prevent a blank render.\");\n }\n\n const layoutStrategy = schema.layoutStrategy || (schema.type === \"array\" ? \"table\" : \"form\");\n const layoutManager = Engine.layoutRegistry.getStrict(layoutStrategy);\n \n return layoutManager.render(schema, modelName, this, onSubmit);\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(\"[MetaUI Engine] Critical error during layout generation\", msg);\n Logger.showErrorPopup(`Engine failed to generate the layout.\\n\\nDetails: ${msg}`);\n return new Text({ text: \"Critical Layout Error\" });\n }\n }\n\n /**\n * Instantiates the correct plugin for a specific field based on type and widget hints,\n * and tracks the plugin for global validation.\n * \n * @param fieldMeta The metadata schema specific to the field.\n * @param bindingPath The JSON path representing the field within the payload.\n * @param modelName The UI5 JSONModel name used for data binding.\n * @returns The generated UI5 Control for the field.\n */\n public generateField(fieldMeta: IPropertyMetadata, bindingPath: string, modelName: string, isTemplate: boolean = false): Control {\n try {\n const plugin = PluginRegistry.getInstance().getPlugin(fieldMeta.type || \"string\", fieldMeta.ui?.widget);\n plugin.setDisplayMode(this.isDisplayMode);\n \n if (!isTemplate) {\n this.activePlugins.push({ plugin, path: bindingPath });\n }\n const scopeId = isTemplate ? undefined : this.engineScopeId;\n const control = plugin.render(fieldMeta, bindingPath, modelName, scopeId, this.onChange);\n \n if (this.conditionEngine) {\n this.conditionEngine.registerPlugin(bindingPath, plugin);\n }\n \n return control;\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI Engine] Failed to generate field at ${bindingPath}`, msg);\n Logger.showErrorPopup(`Failed to generate field '${bindingPath}'.\\n\\nDetails: ${msg}`);\n return new Text({ text: `[Error generating field ${bindingPath}]` });\n }\n }\n\n /**\n * Generates a sub-layout (like an embedded table or nested form) without \n * destroying the current Engine state or Condition tracking.\n * \n * @param schema The normalized JSON schema representing the view.\n * @param modelName The UI5 JSONModel name used for data binding (defaults to \"meta\").\n * @param bindingPath Optional path to bind the sub-layout to a specific array/object property.\n * @returns The generated root UI5 Control container.\n */\n public generateLayout(schema: ISchema, modelName: string, bindingPath?: string): Control {\n try {\n const layoutStrategy = schema.layoutStrategy || (schema.type === \"array\" ? \"table\" : \"form\");\n const layoutManager = Engine.layoutRegistry.getStrict(layoutStrategy);\n return layoutManager.render(schema, modelName, this, undefined, bindingPath);\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI Engine] Critical error generating sub-layout for ${bindingPath}`, msg);\n Logger.showErrorPopup(`Engine failed to generate a sub-layout.\\n\\nDetails: ${msg}`);\n return new Text({ text: \"Critical Sub-Layout Error\" });\n }\n }\n\n /**\n * Iterates through all active plugins and triggers their internal validation pipelines.\n * \n * @returns {IPluginValidationResult[]} Array of validation error objects. Empty array if valid.\n */\n public validateAll(): IPluginValidationResult[] {\n const errors: IPluginValidationResult[] = [];\n for (const item of this.activePlugins) {\n const result = item.plugin.validate();\n if (!result.isValid) {\n // Ensure the path is bound to the error so GeneratorHost knows where to target it\n result.fieldKey = result.fieldKey || item.path.replace(/^\\//, \"\");\n errors.push(result);\n // Add console log to find which plugin fails silently\n Logger.error(\"[MetaUI Validation] Plugin failed validation silently:\", item.path || item.plugin.constructor.name);\n }\n }\n return errors;\n }\n\n /**\n * Cleans up internal state and destroys the condition engine to prevent memory leaks.\n */\n public destroy(): void {\n if (this.conditionEngine) {\n this.conditionEngine.destroy();\n this.conditionEngine = null;\n }\n \n // ------------------------------------------------------------------------\n // Ghost Error Prevention\n // Flush MessageManager for active plugins before destroying their controls\n // ------------------------------------------------------------------------\n const messageManager = Messaging;\n const existingMessages = messageManager.getMessageModel().getData();\n const messagesToRemove: any[] = [];\n \n for (const item of this.activePlugins) {\n if (this.activeModel) {\n const targetPath = `/${item.path.replace(/^\\//, \"\")}`;\n const matched = existingMessages.filter((msg: any) => \n msg.getTarget() === targetPath && msg.getMessageProcessor() && msg.getMessageProcessor().getId() === this.activeModel.getId()\n );\n messagesToRemove.push(...matched);\n }\n if (typeof item.plugin.destroy === \"function\") {\n item.plugin.destroy();\n }\n }\n \n if (messagesToRemove.length > 0) {\n messageManager.removeMessages(messagesToRemove);\n }\n \n this.activePlugins = [];\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"Engine.js","names":["ConditionEngine","___ConditionEngine","PluginRegistry","___PluginRegistry","Logger","___utils_Logger","DefaultLayoutGenerator","___DefaultLayoutGenerator","Engine","conditionEngine","activePlugins","isEditable","constructor","editable","this","build","schema","model","modelName","onSubmit","engineScopeId","onChange","activeModel","isValid","fieldKey","errorMessage","controlId","handleEvent","ensureLayout","warn","layoutStrategy","type","layoutManager","layoutRegistry","getStrict","render","error","msg","message","showErrorPopup","Text","text","generateField","fieldMeta","bindingPath","isTemplate","plugin","getInstance","getPlugin","ui","widget","setEditable","push","path","scopeId","undefined","control","registerPlugin","generateLayout","validateAll","errors","item","result","validate","replace","name","destroy","messageManager","Messaging","existingMessages","getMessageModel","getData","messagesToRemove","targetPath","matched","filter","getTarget","getMessageProcessor","getId","length","removeMessages","__exports","__esModule"],"sources":["Engine.ts"],"sourcesContent":["/**\n * @file Engine.ts\n * @description The central orchestrator that routes data between the Layout Factory and Plugin Registry (v2).\n */\n\nimport { ISchema, IPropertyMetadata } from \"../interfaces/ISchema\";\nimport { ILayoutManager } from \"../interfaces/ILayoutManager\";\nimport { IPlugin, IPluginValidationResult } from \"../interfaces/IPlugin\";\nimport { ConditionEngine } from \"./ConditionEngine\";\nimport { PluginRegistry } from \"./PluginRegistry\";\nimport Control from \"sap/ui/core/Control\";\nimport VBox from \"sap/m/VBox\";\nimport Text from \"sap/m/Text\";\nimport { Registry } from \"./Registry\";\nimport { Logger } from \"../utils/Logger\";\nimport { DefaultLayoutGenerator } from \"./DefaultLayoutGenerator\";\nimport Core from \"sap/ui/core/Core\";\nimport Messaging from \"sap/ui/core/Messaging\";\n\n/**\n * The Engine is responsible for translating a normalized schema into a physical UI5 layout.\n * It delegates layout generation to the configured `LayoutManager` and field generation to the `PluginRegistry`.\n * It is NOT a God Class; it strictly routes execution flow and tracks active plugins for validation.\n * It embodies the \"Plugin-First Philosophy\" by routing all complex field and layout rendering\n * through discrete, decoupled plugins rather than handling native overrides.\n * \n * @namespace nz.co.siliconst.ui5.metaui.core\n * @public\n */\nexport class Engine {\n /** Global registry of all available layout strategies (e.g. Form, Table, Wizard). */\n public static layoutRegistry: Registry<ILayoutManager>;\n /** Handles dynamic conditional logic across the active form. */\n private conditionEngine: ConditionEngine | null = null;\n \n /** Array of all instantiated plugins generated during the current build. */\n private activePlugins: { plugin: IPlugin, path: string }[] = [];\n\n /** Deterministic scope ID injected by the host control to prevent clone collisions. */\n public engineScopeId?: string;\n \n private activeModel?: sap.ui.model.Model;\n \n /** Tracks whether the entire engine is running in Editable mode. */\n public readonly isEditable: boolean = true;\n\n constructor(editable: boolean = true) {\n this.isEditable = editable;\n }\n \n /**\n * Bootstraps the layout generation process by resolving the correct layout strategy.\n * \n * @param schema The normalized JSON schema representing the view.\n * @param model The active StateManager JSONModel instance.\n * @param modelName The UI5 model alias used for isolation.\n * @param onSubmit Callback fired when form is submitted.\n * @param engineScopeId Deterministic scope ID for this engine instance.\n * @param onChange Callback fired when field values change.\n * @returns The generated root UI5 Control container.\n */\n public build(schema: ISchema, model: sap.ui.model.Model, modelName: string = \"meta\", onSubmit?: () => void, engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.conditionEngine = new ConditionEngine(schema);\n this.activePlugins = [];\n this.activeModel = model;\n this.engineScopeId = engineScopeId;\n this.onChange = (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => {\n if (this.conditionEngine && fieldKey) {\n this.conditionEngine.handleEvent(fieldKey, isValid);\n }\n if (onChange) {\n onChange(isValid, fieldKey, errorMessage, controlId);\n }\n };\n \n try {\n // Intercept and synthesize a default layout if the developer/backend failed to provide one\n if (DefaultLayoutGenerator.ensureLayout(schema)) {\n Logger.warn(\"[MetaUI Engine] Missing 'uiLayout' array in schema. Synthesized a default layout mapping to prevent a blank render.\");\n }\n\n const layoutStrategy = schema.layoutStrategy || (schema.type === \"array\" ? \"table\" : \"form\");\n const layoutManager = Engine.layoutRegistry.getStrict(layoutStrategy);\n \n return layoutManager.render(schema, modelName, this, onSubmit);\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(\"[MetaUI Engine] Critical error during layout generation\", msg);\n Logger.showErrorPopup(`Engine failed to generate the layout.\\n\\nDetails: ${msg}`);\n return new Text({ text: \"Critical Layout Error\" });\n }\n }\n\n /**\n * Instantiates the correct plugin for a specific field based on type and widget hints,\n * and tracks the plugin for global validation.\n * \n * @param fieldMeta The metadata schema specific to the field.\n * @param bindingPath The JSON path representing the field within the payload.\n * @param modelName The UI5 JSONModel name used for data binding.\n * @returns The generated UI5 Control for the field.\n */\n public generateField(fieldMeta: IPropertyMetadata, bindingPath: string, modelName: string, isTemplate: boolean = false): Control {\n try {\n const plugin = PluginRegistry.getInstance().getPlugin(fieldMeta.type || \"string\", fieldMeta.ui?.widget);\n plugin.setEditable(this.isEditable);\n \n if (!isTemplate) {\n this.activePlugins.push({ plugin, path: bindingPath });\n }\n const scopeId = isTemplate ? undefined : this.engineScopeId;\n const control = plugin.render(fieldMeta, bindingPath, modelName, scopeId, this.onChange);\n \n if (this.conditionEngine) {\n this.conditionEngine.registerPlugin(bindingPath, plugin);\n }\n \n return control;\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI Engine] Failed to generate field at ${bindingPath}`, msg);\n Logger.showErrorPopup(`Failed to generate field '${bindingPath}'.\\n\\nDetails: ${msg}`);\n return new Text({ text: `[Error generating field ${bindingPath}]` });\n }\n }\n\n /**\n * Generates a sub-layout (like an embedded table or nested form) without \n * destroying the current Engine state or Condition tracking.\n * \n * @param schema The normalized JSON schema representing the view.\n * @param modelName The UI5 JSONModel name used for data binding (defaults to \"meta\").\n * @param bindingPath Optional path to bind the sub-layout to a specific array/object property.\n * @returns The generated root UI5 Control container.\n */\n public generateLayout(schema: ISchema, modelName: string, bindingPath?: string): Control {\n try {\n const layoutStrategy = schema.layoutStrategy || (schema.type === \"array\" ? \"table\" : \"form\");\n const layoutManager = Engine.layoutRegistry.getStrict(layoutStrategy);\n return layoutManager.render(schema, modelName, this, undefined, bindingPath);\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI Engine] Critical error generating sub-layout for ${bindingPath}`, msg);\n Logger.showErrorPopup(`Engine failed to generate a sub-layout.\\n\\nDetails: ${msg}`);\n return new Text({ text: \"Critical Sub-Layout Error\" });\n }\n }\n\n /**\n * Iterates through all active plugins and triggers their internal validation pipelines.\n * \n * @returns {IPluginValidationResult[]} Array of validation error objects. Empty array if valid.\n */\n public validateAll(): IPluginValidationResult[] {\n const errors: IPluginValidationResult[] = [];\n for (const item of this.activePlugins) {\n const result = item.plugin.validate();\n if (!result.isValid) {\n // Ensure the path is bound to the error so GeneratorHost knows where to target it\n result.fieldKey = result.fieldKey || item.path.replace(/^\\//, \"\");\n errors.push(result);\n // Add console log to find which plugin fails silently\n Logger.error(\"[MetaUI Validation] Plugin failed validation silently:\", item.path || item.plugin.constructor.name);\n }\n }\n return errors;\n }\n\n /**\n * Cleans up internal state and destroys the condition engine to prevent memory leaks.\n */\n public destroy(): void {\n if (this.conditionEngine) {\n this.conditionEngine.destroy();\n this.conditionEngine = null;\n }\n \n // ------------------------------------------------------------------------\n // Ghost Error Prevention\n // Flush MessageManager for active plugins before destroying their controls\n // ------------------------------------------------------------------------\n const messageManager = Messaging;\n const existingMessages = messageManager.getMessageModel().getData();\n const messagesToRemove: any[] = [];\n \n for (const item of this.activePlugins) {\n if (this.activeModel) {\n const targetPath = `/${item.path.replace(/^\\//, \"\")}`;\n const matched = existingMessages.filter((msg: any) => \n msg.getTarget() === targetPath && msg.getMessageProcessor() && msg.getMessageProcessor().getId() === this.activeModel.getId()\n );\n messagesToRemove.push(...matched);\n }\n if (typeof item.plugin.destroy === \"function\") {\n item.plugin.destroy();\n }\n }\n \n if (messagesToRemove.length > 0) {\n messageManager.removeMessages(messagesToRemove);\n }\n \n this.activePlugins = [];\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -41,11 +41,11 @@ export class Engine {
41
41
 
42
42
  private activeModel?: sap.ui.model.Model;
43
43
 
44
- /** Tracks whether the entire engine is running in Read-Only Display mode. */
45
- public readonly isDisplayMode: boolean = false;
44
+ /** Tracks whether the entire engine is running in Editable mode. */
45
+ public readonly isEditable: boolean = true;
46
46
 
47
- constructor(displayMode: boolean = false) {
48
- this.isDisplayMode = displayMode;
47
+ constructor(editable: boolean = true) {
48
+ this.isEditable = editable;
49
49
  }
50
50
 
51
51
  /**
@@ -103,7 +103,7 @@ export class Engine {
103
103
  public generateField(fieldMeta: IPropertyMetadata, bindingPath: string, modelName: string, isTemplate: boolean = false): Control {
104
104
  try {
105
105
  const plugin = PluginRegistry.getInstance().getPlugin(fieldMeta.type || "string", fieldMeta.ui?.widget);
106
- plugin.setDisplayMode(this.isDisplayMode);
106
+ plugin.setEditable(this.isEditable);
107
107
 
108
108
  if (!isTemplate) {
109
109
  this.activePlugins.push({ plugin, path: bindingPath });
@@ -165,19 +165,23 @@ sap.ui.define(["../utils/Logger"], function (___utils_Logger) {
165
165
  for (const key of Object.keys(obj)) {
166
166
  const val = obj[key];
167
167
  if (val === null || val === undefined) continue;
168
- if (typeof val === "object" && !Array.isArray(val)) continue;
169
168
  let type = "string";
170
169
  let items;
170
+ let nestedProps;
171
171
  if (typeof val === "number") type = "number";else if (typeof val === "boolean") type = "boolean";else if (Array.isArray(val)) {
172
172
  type = "array";
173
173
  items = {
174
174
  type: "object",
175
175
  properties: val.length > 0 ? this.inferPropertiesFromObject(val[0]) : {}
176
176
  };
177
+ } else if (typeof val === "object") {
178
+ type = "object";
179
+ nestedProps = this.inferPropertiesFromObject(val);
177
180
  }
178
181
  properties[key] = {
179
182
  type,
180
183
  items,
184
+ properties: nestedProps,
181
185
  ui: {
182
186
  label: this.generateLabel(key),
183
187
  isKey: false,
@@ -187,6 +191,46 @@ sap.ui.define(["../utils/Logger"], function (___utils_Logger) {
187
191
  }
188
192
  return properties;
189
193
  }
194
+
195
+ /**
196
+ * Resolves a JSON Schema scope (e.g. '#/properties/header/properties/id')
197
+ * against the ISchema, returning the PropertyMetadata and the UI5 binding path.
198
+ */
199
+ static resolveScope(schema, scope) {
200
+ if (!scope || !scope.startsWith("#/properties/")) {
201
+ return {
202
+ meta: undefined,
203
+ bindingPath: scope || "",
204
+ propKey: scope || ""
205
+ };
206
+ }
207
+ const pathSegments = scope.replace("#/properties/", "").split("/properties/");
208
+ let current = schema.properties;
209
+ let meta;
210
+ Logger.debug("[MetaUI SchemaNormalizer]", `Resolving scope '${scope}' with segments: ${JSON.stringify(pathSegments)}`, "SchemaNormalizer");
211
+ Logger.debug("[MetaUI SchemaNormalizer]", `Root schema keys: ${Object.keys(schema.properties || {})}`, "SchemaNormalizer");
212
+ for (let i = 0; i < pathSegments.length; i++) {
213
+ const segment = pathSegments[i];
214
+ if (!current) {
215
+ Logger.debug("[MetaUI SchemaNormalizer]", `current is undefined at segment '${segment}'`, "SchemaNormalizer");
216
+ meta = undefined;
217
+ break;
218
+ }
219
+ meta = current[segment];
220
+ Logger.debug("[MetaUI SchemaNormalizer]", `Segment '${segment}' resolved to meta: ${!!meta}. Available keys in current: ${Object.keys(current)}`, "SchemaNormalizer");
221
+ if (i < pathSegments.length - 1) {
222
+ current = meta?.properties;
223
+ }
224
+ }
225
+ const bindingPath = pathSegments.join("/");
226
+ const propKey = scope.replace("#/properties/", ""); // The original raw string for logging
227
+
228
+ return {
229
+ meta,
230
+ bindingPath,
231
+ propKey
232
+ };
233
+ }
190
234
  }
191
235
  var __exports = {
192
236
  __esModule: true