@openui5/sap.ui.rta 1.144.0 → 1.145.1

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 (163) hide show
  1. package/.eslintrc.json +7 -1
  2. package/REUSE.toml +40 -16
  3. package/THIRDPARTY.txt +22 -1
  4. package/package.json +6 -6
  5. package/src/sap/ui/rta/.library +1 -1
  6. package/src/sap/ui/rta/Client.js +1 -1
  7. package/src/sap/ui/rta/RuntimeAuthoring.js +8 -6
  8. package/src/sap/ui/rta/Utils.js +4 -2
  9. package/src/sap/ui/rta/appVariant/AppVariantManager.js +2 -2
  10. package/src/sap/ui/rta/appVariant/Feature.js +6 -4
  11. package/src/sap/ui/rta/appVariant/S4HanaCloudBackend.js +6 -3
  12. package/src/sap/ui/rta/appVariant/Utils.js +2 -2
  13. package/src/sap/ui/rta/command/AddIFrame.js +1 -1
  14. package/src/sap/ui/rta/command/AddProperty.js +1 -1
  15. package/src/sap/ui/rta/command/AddXML.js +1 -1
  16. package/src/sap/ui/rta/command/AddXMLAtExtensionPoint.js +1 -1
  17. package/src/sap/ui/rta/command/AnnotationCommand.js +1 -1
  18. package/src/sap/ui/rta/command/BaseCommand.js +1 -1
  19. package/src/sap/ui/rta/command/BindProperty.js +1 -1
  20. package/src/sap/ui/rta/command/Combine.js +1 -1
  21. package/src/sap/ui/rta/command/CommandFactory.js +1 -1
  22. package/src/sap/ui/rta/command/CompositeCommand.js +1 -1
  23. package/src/sap/ui/rta/command/ControlVariantConfigure.js +2 -1
  24. package/src/sap/ui/rta/command/ControlVariantSave.js +1 -1
  25. package/src/sap/ui/rta/command/ControlVariantSaveAs.js +1 -1
  26. package/src/sap/ui/rta/command/ControlVariantSetTitle.js +1 -1
  27. package/src/sap/ui/rta/command/ControlVariantSwitch.js +1 -1
  28. package/src/sap/ui/rta/command/CreateContainer.js +1 -1
  29. package/src/sap/ui/rta/command/CustomAdd.js +1 -1
  30. package/src/sap/ui/rta/command/ExtendControllerCommand.js +1 -1
  31. package/src/sap/ui/rta/command/FlexCommand.js +1 -1
  32. package/src/sap/ui/rta/command/LREPSerializer.js +1 -1
  33. package/src/sap/ui/rta/command/LocalReset.js +1 -1
  34. package/src/sap/ui/rta/command/ManifestCommand.js +1 -1
  35. package/src/sap/ui/rta/command/Move.js +1 -1
  36. package/src/sap/ui/rta/command/Property.js +1 -1
  37. package/src/sap/ui/rta/command/Remove.js +1 -1
  38. package/src/sap/ui/rta/command/Rename.js +1 -1
  39. package/src/sap/ui/rta/command/Resize.js +1 -1
  40. package/src/sap/ui/rta/command/Reveal.js +1 -1
  41. package/src/sap/ui/rta/command/Settings.js +1 -1
  42. package/src/sap/ui/rta/command/Split.js +1 -1
  43. package/src/sap/ui/rta/command/Stack.js +1 -1
  44. package/src/sap/ui/rta/command/compVariant/CompVariantContent.js +1 -1
  45. package/src/sap/ui/rta/command/compVariant/CompVariantSaveAs.js +1 -1
  46. package/src/sap/ui/rta/command/compVariant/CompVariantSwitch.js +1 -1
  47. package/src/sap/ui/rta/command/compVariant/CompVariantUpdate.js +1 -1
  48. package/src/sap/ui/rta/command/manifest/AddLibrary.js +1 -1
  49. package/src/sap/ui/rta/enablement/elementActionTest.js +90 -94
  50. package/src/sap/ui/rta/library.js +2 -2
  51. package/src/sap/ui/rta/messagebundle.properties +1 -1
  52. package/src/sap/ui/rta/messagebundle_ar.properties +1 -1
  53. package/src/sap/ui/rta/messagebundle_bg.properties +1 -1
  54. package/src/sap/ui/rta/messagebundle_ca.properties +1 -1
  55. package/src/sap/ui/rta/messagebundle_cnr.properties +1 -1
  56. package/src/sap/ui/rta/messagebundle_cs.properties +1 -1
  57. package/src/sap/ui/rta/messagebundle_cy.properties +1 -1
  58. package/src/sap/ui/rta/messagebundle_da.properties +1 -1
  59. package/src/sap/ui/rta/messagebundle_de.properties +1 -1
  60. package/src/sap/ui/rta/messagebundle_el.properties +1 -1
  61. package/src/sap/ui/rta/messagebundle_en.properties +1 -1
  62. package/src/sap/ui/rta/messagebundle_en_GB.properties +1 -1
  63. package/src/sap/ui/rta/messagebundle_en_US_saprigi.properties +3 -3
  64. package/src/sap/ui/rta/messagebundle_es.properties +1 -1
  65. package/src/sap/ui/rta/messagebundle_es_MX.properties +1 -1
  66. package/src/sap/ui/rta/messagebundle_et.properties +1 -1
  67. package/src/sap/ui/rta/messagebundle_fi.properties +1 -1
  68. package/src/sap/ui/rta/messagebundle_fr.properties +1 -1
  69. package/src/sap/ui/rta/messagebundle_fr_CA.properties +2 -2
  70. package/src/sap/ui/rta/messagebundle_hi.properties +1 -1
  71. package/src/sap/ui/rta/messagebundle_hr.properties +1 -1
  72. package/src/sap/ui/rta/messagebundle_hu.properties +1 -1
  73. package/src/sap/ui/rta/messagebundle_id.properties +1 -1
  74. package/src/sap/ui/rta/messagebundle_it.properties +1 -1
  75. package/src/sap/ui/rta/messagebundle_iw.properties +1 -1
  76. package/src/sap/ui/rta/messagebundle_ja.properties +1 -1
  77. package/src/sap/ui/rta/messagebundle_kk.properties +1 -1
  78. package/src/sap/ui/rta/messagebundle_ko.properties +1 -1
  79. package/src/sap/ui/rta/messagebundle_lt.properties +1 -1
  80. package/src/sap/ui/rta/messagebundle_lv.properties +1 -1
  81. package/src/sap/ui/rta/messagebundle_mk.properties +1 -1
  82. package/src/sap/ui/rta/messagebundle_ms.properties +1 -1
  83. package/src/sap/ui/rta/messagebundle_nl.properties +1 -1
  84. package/src/sap/ui/rta/messagebundle_no.properties +1 -1
  85. package/src/sap/ui/rta/messagebundle_pl.properties +1 -1
  86. package/src/sap/ui/rta/messagebundle_pt.properties +1 -1
  87. package/src/sap/ui/rta/messagebundle_pt_PT.properties +1 -1
  88. package/src/sap/ui/rta/messagebundle_ro.properties +1 -1
  89. package/src/sap/ui/rta/messagebundle_ru.properties +1 -1
  90. package/src/sap/ui/rta/messagebundle_sh.properties +1 -1
  91. package/src/sap/ui/rta/messagebundle_sk.properties +1 -1
  92. package/src/sap/ui/rta/messagebundle_sl.properties +1 -1
  93. package/src/sap/ui/rta/messagebundle_sr.properties +1 -1
  94. package/src/sap/ui/rta/messagebundle_sv.properties +1 -1
  95. package/src/sap/ui/rta/messagebundle_th.properties +1 -1
  96. package/src/sap/ui/rta/messagebundle_tr.properties +1 -1
  97. package/src/sap/ui/rta/messagebundle_uk.properties +1 -1
  98. package/src/sap/ui/rta/messagebundle_vi.properties +1 -1
  99. package/src/sap/ui/rta/messagebundle_zh_CN.properties +1 -1
  100. package/src/sap/ui/rta/messagebundle_zh_TW.properties +1 -1
  101. package/src/sap/ui/rta/plugin/AddXMLAtExtensionPoint.js +4 -4
  102. package/src/sap/ui/rta/plugin/AddXMLPlugin.js +1 -1
  103. package/src/sap/ui/rta/plugin/BaseCreate.js +1 -1
  104. package/src/sap/ui/rta/plugin/Combine.js +1 -1
  105. package/src/sap/ui/rta/plugin/ControlVariant.js +1 -1
  106. package/src/sap/ui/rta/plugin/CreateContainer.js +1 -1
  107. package/src/sap/ui/rta/plugin/CutPaste.js +1 -1
  108. package/src/sap/ui/rta/plugin/DragDrop.js +1 -1
  109. package/src/sap/ui/rta/plugin/ExtendControllerPlugin.js +1 -1
  110. package/src/sap/ui/rta/plugin/LocalReset.js +1 -1
  111. package/src/sap/ui/rta/plugin/Plugin.js +1 -1
  112. package/src/sap/ui/rta/plugin/RTAElementMover.js +1 -1
  113. package/src/sap/ui/rta/plugin/Remove.js +13 -11
  114. package/src/sap/ui/rta/plugin/Resize.js +1 -1
  115. package/src/sap/ui/rta/plugin/Selection.js +1 -1
  116. package/src/sap/ui/rta/plugin/Settings.js +1 -1
  117. package/src/sap/ui/rta/plugin/Split.js +1 -1
  118. package/src/sap/ui/rta/plugin/Stretch.js +1 -1
  119. package/src/sap/ui/rta/plugin/additionalElements/ActionExtractor.js +1 -1
  120. package/src/sap/ui/rta/plugin/additionalElements/AddElementsDialog.fragment.xml +3 -20
  121. package/src/sap/ui/rta/plugin/additionalElements/AddElementsDialog.js +278 -26
  122. package/src/sap/ui/rta/plugin/additionalElements/AdditionalElementsAnalyzer.js +40 -11
  123. package/src/sap/ui/rta/plugin/additionalElements/AdditionalElementsPlugin.js +4 -3
  124. package/src/sap/ui/rta/plugin/additionalElements/AdditionalElementsUtils.js +1 -1
  125. package/src/sap/ui/rta/plugin/additionalElements/CommandBuilder.js +1 -1
  126. package/src/sap/ui/rta/plugin/annotations/AnnotationChangeDialog.fragment.xml +1 -1
  127. package/src/sap/ui/rta/plugin/annotations/AnnotationChangeDialog.js +29 -4
  128. package/src/sap/ui/rta/plugin/annotations/AnnotationChangeDialogController.js +11 -17
  129. package/src/sap/ui/rta/plugin/annotations/AnnotationPlugin.js +8 -6
  130. package/src/sap/ui/rta/plugin/annotations/DocumentedAnnotationChanges.js +14 -0
  131. package/src/sap/ui/rta/plugin/iframe/AddIFrame.js +14 -12
  132. package/src/sap/ui/rta/plugin/iframe/AddIFrameDialog.fragment.xml +4 -4
  133. package/src/sap/ui/rta/plugin/iframe/AddIFrameDialog.js +8 -1
  134. package/src/sap/ui/rta/plugin/iframe/AddIFrameDialogController.js +31 -19
  135. package/src/sap/ui/rta/plugin/rename/Rename.js +1 -1
  136. package/src/sap/ui/rta/plugin/rename/RenameDialog.js +1 -1
  137. package/src/sap/ui/rta/service/Action.js +1 -1
  138. package/src/sap/ui/rta/service/ControllerExtension.js +1 -1
  139. package/src/sap/ui/rta/service/Outline.js +14 -6
  140. package/src/sap/ui/rta/service/Property.js +1 -1
  141. package/src/sap/ui/rta/service/Selection.js +1 -1
  142. package/src/sap/ui/rta/service/SupportTools.js +1 -1
  143. package/src/sap/ui/rta/toolbar/Adaptation.js +6 -3
  144. package/src/sap/ui/rta/toolbar/Base.js +1 -1
  145. package/src/sap/ui/rta/toolbar/Fiori.js +1 -1
  146. package/src/sap/ui/rta/toolbar/FioriLike.js +1 -1
  147. package/src/sap/ui/rta/toolbar/OverflowToolbarButton.js +1 -1
  148. package/src/sap/ui/rta/toolbar/Standalone.js +1 -1
  149. package/src/sap/ui/rta/toolbar/contextBased/ManageAdaptations.js +13 -11
  150. package/src/sap/ui/rta/toolbar/contextBased/SaveAsAdaptation.js +1 -1
  151. package/src/sap/ui/rta/toolbar/translation/Translation.js +1 -1
  152. package/src/sap/ui/rta/toolbar/versioning/Versioning.js +1 -1
  153. package/src/sap/ui/rta/util/PluginManager.js +1 -1
  154. package/src/sap/ui/rta/util/PopupManager.js +1 -1
  155. package/src/sap/ui/rta/util/ReloadManager.js +1 -1
  156. package/src/sap/ui/rta/util/ServiceEventBus.js +1 -1
  157. package/src/sap/ui/rta/util/ServiceManager.js +1 -1
  158. package/src/sap/ui/rta/util/changeVisualization/ChangeIndicator.js +1 -1
  159. package/src/sap/ui/rta/util/changeVisualization/ChangeIndicatorRegistry.js +1 -1
  160. package/src/sap/ui/rta/util/changeVisualization/ChangeVisualization.js +1 -1
  161. package/src/sap/ui/rta/util/changeVisualization/resolveBinding.js +1 -1
  162. package/src/sap/ui/rta/util/guidedTour/GuidedTour.js +1 -1
  163. package/src/sap/ui/rta/util/whatsNew/WhatsNew.js +1 -1
@@ -31,7 +31,7 @@ sap.ui.define([
31
31
  * @class The Selection plugin allows you to select or focus overlays with mouse or keyboard and navigate to others.
32
32
  * @extends sap.ui.rta.plugin.Plugin
33
33
  * @author SAP SE
34
- * @version 1.144.0
34
+ * @version 1.145.1
35
35
  * @constructor
36
36
  * @private
37
37
  * @since 1.34
@@ -30,7 +30,7 @@ sap.ui.define([
30
30
  * @class The Settings allows trigger change of settings operations on the overlay
31
31
  * @extends sap.ui.rta.plugin.Plugin
32
32
  * @author SAP SE
33
- * @version 1.144.0
33
+ * @version 1.145.1
34
34
  * @constructor
35
35
  * @private
36
36
  * @since 1.44
@@ -23,7 +23,7 @@ sap.ui.define([
23
23
  * @class
24
24
  * @extends sap.ui.rta.plugin.Plugin
25
25
  * @author SAP SE
26
- * @version 1.144.0
26
+ * @version 1.145.1
27
27
  * @constructor
28
28
  * @private
29
29
  * @since 1.46
@@ -29,7 +29,7 @@ sap.ui.define([
29
29
  * @extends sap.ui.rta.plugin.Plugin
30
30
  *
31
31
  * @author SAP SE
32
- * @version 1.144.0
32
+ * @version 1.145.1
33
33
  *
34
34
  * @constructor
35
35
  * @private
@@ -32,7 +32,7 @@ sap.ui.define([
32
32
  * handled by the AdditionalElements Plugin (Reveal, Add Via Delegate, Add Custom)
33
33
  *
34
34
  * @author SAP SE
35
- * @version 1.144.0
35
+ * @version 1.145.1
36
36
  * @private
37
37
  * @since 1.94
38
38
  */
@@ -64,26 +64,9 @@
64
64
  id="rta_addElementsDialogList"
65
65
  mode="MultiSelect"
66
66
  includeItemInSelection="true"
67
- growing="true"
68
- growingScrollToLoad="true"
69
- items="{ path: '/elements', sorter: { path: 'label', descending: false}, templateShareable: false }"
70
- noDataText="{i18n>MSG_NO_FIELDS}">
71
- <CustomListItem
72
- class="sapUIRtaListItem"
73
- type="Active"
74
- selected="{selected}"
75
- tooltip="{tooltip}">
76
- <VBox>
77
- <Label
78
- design="Standard"
79
- text="{= ${parentPropertyName} &amp;&amp; ${duplicateName} ? ${label} + ' (' + ${parentPropertyName} + ')' : ${label} }"/>
80
- <Label
81
- text="{= ${originalLabel} ? ${i18n>LBL_FREP}.replace('{0}', ${originalLabel}) : ''}"
82
- visible="{= !!${originalLabel} }"/>
83
- </VBox>
84
- </CustomListItem>
85
- </List>
67
+ items="{ path: '/elementsFlat', factory: '._createListItem' }"
68
+ noDataText="{i18n>MSG_NO_FIELDS}"/>
86
69
  </ScrollContainer>
87
70
  </content>
88
71
  </Dialog>
89
- </core:FragmentDefinition>
72
+ </core:FragmentDefinition>
@@ -4,24 +4,28 @@
4
4
  * Licensed under the Apache License, Version 2.0 - see LICENSE.txt.
5
5
  */
6
6
  sap.ui.define([
7
+ "sap/m/CustomListItem",
8
+ "sap/m/FormattedText",
9
+ "sap/m/GroupHeaderListItem",
10
+ "sap/m/VBox",
7
11
  "sap/ui/base/ManagedObject",
8
12
  "sap/ui/core/Element",
9
13
  "sap/ui/core/Fragment",
14
+ "sap/ui/fl/util/CancelError",
10
15
  "sap/ui/model/json/JSONModel",
11
- "sap/ui/model/Filter",
12
- "sap/ui/model/FilterOperator",
13
16
  "sap/ui/model/resource/ResourceModel",
14
- "sap/ui/model/Sorter",
15
17
  "sap/ui/rta/Utils"
16
18
  ], function(
19
+ CustomListItem,
20
+ FormattedText,
21
+ GroupHeaderListItem,
22
+ VBox,
17
23
  ManagedObject,
18
24
  Element,
19
25
  Fragment,
26
+ CancelError,
20
27
  JSONModel,
21
- Filter,
22
- FilterOperator,
23
28
  ResourceModel,
24
- Sorter,
25
29
  Utils
26
30
  ) {
27
31
  "use strict";
@@ -32,7 +36,7 @@ sap.ui.define([
32
36
  * @class Context - Dialog for available Fields in Runtime Authoring
33
37
  * @extends sap.ui.base.ManagedObject
34
38
  * @author SAP SE
35
- * @version 1.144.0
39
+ * @version 1.145.1
36
40
  * @constructor
37
41
  * @private
38
42
  * @since 1.44
@@ -57,6 +61,154 @@ sap.ui.define([
57
61
  }
58
62
  });
59
63
 
64
+ /**
65
+ * Highlights matching text by wrapping it in <strong> tags.
66
+ * Escapes HTML in the text to prevent XSS.
67
+ *
68
+ * @param {string} sText - The text to process
69
+ * @param {string} sSearchValue - The search value to highlight
70
+ * @returns {string} The text with matching parts wrapped in <strong> tags
71
+ * @private
72
+ */
73
+ function highlightText(sText, sSearchValue) {
74
+ if (!sText) {
75
+ return "";
76
+ }
77
+ if (!sSearchValue) {
78
+ return encodeXML(sText);
79
+ }
80
+
81
+ const sLowerText = sText.toLowerCase();
82
+ const sLowerSearch = sSearchValue.toLowerCase();
83
+ const iIndex = sLowerText.indexOf(sLowerSearch);
84
+
85
+ if (iIndex === -1) {
86
+ return encodeXML(sText);
87
+ }
88
+
89
+ // Split the text into parts: before match, match, after match
90
+ const sBefore = sText.substring(0, iIndex);
91
+ const sMatch = sText.substring(iIndex, iIndex + sSearchValue.length);
92
+ const sAfter = sText.substring(iIndex + sSearchValue.length);
93
+
94
+ // Recursively highlight the rest of the text (for multiple occurrences)
95
+ return `${encodeXML(sBefore)}<strong>${encodeXML(sMatch)}</strong>${highlightText(sAfter, sSearchValue)}`;
96
+ }
97
+
98
+ /**
99
+ * Encodes special XML/HTML characters to prevent XSS.
100
+ *
101
+ * @param {string} sText - The text to encode
102
+ * @returns {string} The encoded text
103
+ * @private
104
+ */
105
+ function encodeXML(sText) {
106
+ if (!sText) {
107
+ return "";
108
+ }
109
+ return sText
110
+ .replace(/&/g, "&amp;")
111
+ .replace(/</g, "&lt;")
112
+ .replace(/>/g, "&gt;")
113
+ .replace(/"/g, "&quot;")
114
+ .replace(/'/g, "&#39;");
115
+ }
116
+
117
+ /**
118
+ * Transforms flat elements array into a flat list with group headers.
119
+ * Elements without entityTypeDisplayName are placed at the root level (top).
120
+ * Elements with entityTypeDisplayName are grouped under their entity name with a group header.
121
+ *
122
+ * @param {object[]} aElements - Flat array of elements
123
+ * @param {string} [sFilterValue] - Optional filter value to filter elements
124
+ * @private
125
+ */
126
+ function buildElementsList(aElements, sFilterValue) {
127
+ const aRootElements = [];
128
+ const mGroups = {};
129
+
130
+ // Filter elements if filter value is provided
131
+ const aFilteredElements = sFilterValue
132
+ ? aElements.filter((oElement) => this._elementMatchesFilter(oElement, sFilterValue))
133
+ : aElements;
134
+
135
+ // Separate elements into root elements and grouped elements
136
+ aFilteredElements.forEach(function(oElement) {
137
+ if (oElement.entityTypeDisplayName) {
138
+ // Element belongs to an entity group
139
+ mGroups[oElement.entityTypeDisplayName] ||= [];
140
+ mGroups[oElement.entityTypeDisplayName].push(oElement);
141
+ } else {
142
+ // Element has no entity - place at root level
143
+ aRootElements.push(oElement);
144
+ }
145
+ });
146
+
147
+ // Sort root elements
148
+ const bDescending = this._bDescendingSortOrder;
149
+ aRootElements.sort(function(a, b) {
150
+ const sLabelA = (a.label || "").toLowerCase();
151
+ const sLabelB = (b.label || "").toLowerCase();
152
+ if (sLabelA < sLabelB) {
153
+ return bDescending ? 1 : -1;
154
+ }
155
+ if (sLabelA > sLabelB) {
156
+ return bDescending ? -1 : 1;
157
+ }
158
+ return 0;
159
+ });
160
+
161
+ // Build flat list: root elements first, then group headers with their elements
162
+ const aFlatList = [];
163
+
164
+ // Add root elements (without entityTypeDisplayName) first
165
+ aRootElements.forEach(function(oElement) {
166
+ aFlatList.push(oElement);
167
+ });
168
+
169
+ // Add groups with their elements (groups sorted alphabetically, elements sorted by label)
170
+ const aGroupNames = Object.keys(mGroups);
171
+ aGroupNames.sort(function(a, b) {
172
+ const sNameA = a.toLowerCase();
173
+ const sNameB = b.toLowerCase();
174
+ if (sNameA < sNameB) {
175
+ return bDescending ? 1 : -1;
176
+ }
177
+ if (sNameA > sNameB) {
178
+ return bDescending ? -1 : 1;
179
+ }
180
+ return 0;
181
+ });
182
+
183
+ aGroupNames.forEach(function(sEntityName) {
184
+ // Add group header
185
+ aFlatList.push({
186
+ label: sEntityName,
187
+ isGroupHeader: true
188
+ });
189
+
190
+ // Sort and add elements within this group
191
+ const aGroupElements = mGroups[sEntityName];
192
+ aGroupElements.sort(function(a, b) {
193
+ const sLabelA = (a.label || "").toLowerCase();
194
+ const sLabelB = (b.label || "").toLowerCase();
195
+ if (sLabelA < sLabelB) {
196
+ return bDescending ? 1 : -1;
197
+ }
198
+ if (sLabelA > sLabelB) {
199
+ return bDescending ? -1 : 1;
200
+ }
201
+ return 0;
202
+ });
203
+
204
+ aGroupElements.forEach(function(oElement) {
205
+ aFlatList.push(oElement);
206
+ });
207
+ });
208
+
209
+ this._oDialogModel.setProperty("/elementsFlat", aFlatList);
210
+ }
211
+
60
212
  /**
61
213
  * Initialize the Dialog
62
214
  *
@@ -69,12 +221,15 @@ sap.ui.define([
69
221
  customFieldButtonVisible: false,
70
222
  businessContextVisible: false,
71
223
  customFieldButtonTooltip: "",
72
- businessContextTexts: [{ text: "" }], // empty element in first place to be replaced by the headerText (see: addExtensibilityInfo)
224
+ // empty element in first place to be replaced by the headerText (see: addExtensibilityInfo)
225
+ businessContextTexts: [{ text: "" }],
73
226
  extensibilityMenuButtonActive: false,
74
227
  extensibilityMenuButtonText: "",
75
228
  extensibilityMenuButtonTooltip: "",
76
229
  extensibilityOptions: []
77
230
  });
231
+ // Increase the default size limit (100) to allow for large numbers of elements. More than 1000 causes performance issues.
232
+ this._oDialogModel.setSizeLimit(1000);
78
233
 
79
234
  this._bDescendingSortOrder = false;
80
235
  this.oRTAResourceModel = new ResourceModel({ bundleName: "sap.ui.rta.messagebundle" });
@@ -111,6 +266,7 @@ sap.ui.define([
111
266
  // retrieve List to set the sorting for the 'items' aggregation, since sap.ui.model.Sorter
112
267
  // does not support binding to a model property...
113
268
  this._oList = Element.getElementById(`${this.getId()}--rta_addElementsDialogList`);
269
+
114
270
  this._openDialog();
115
271
  }.bind(this));
116
272
  };
@@ -161,11 +317,17 @@ sap.ui.define([
161
317
  });
162
318
  this._oDialog.close();
163
319
  // indicate that the dialog has been closed without choosing to add any fields (canceled)
164
- this._fnRejectOnDialogCancel();
320
+ this._fnRejectOnDialogCancel(new CancelError());
165
321
  };
166
322
 
167
323
  AddElementsDialog.prototype.setElements = function(aElements) {
324
+ if (aElements.length > 1000) {
325
+ throw new Error("AddElementsDialog: displaying more than 1000 elements is not supported.");
326
+ }
168
327
  this._oDialogModel.setProperty("/elements", aElements);
328
+ // Reset filter when new elements are set (e.g., when dialog is reopened)
329
+ this._sCurrentFilterValue = "";
330
+ buildElementsList.call(this, aElements);
169
331
  };
170
332
 
171
333
  AddElementsDialog.prototype.getElements = function() {
@@ -193,38 +355,128 @@ sap.ui.define([
193
355
  };
194
356
 
195
357
  /**
196
- * Resort the list
358
+ * Factory function to create list items.
359
+ * Creates GroupHeaderListItem for group headers and CustomListItem for regular elements.
360
+ *
361
+ * @param {string} sId - The ID for the new item
362
+ * @param {sap.ui.model.Context} oContext - The binding context
363
+ * @returns {sap.m.ListItemBase} The created list item
364
+ * @private
365
+ */
366
+ AddElementsDialog.prototype._createListItem = function(sId, oContext) {
367
+ const oData = oContext.getObject();
368
+
369
+ if (oData.isGroupHeader) {
370
+ // Create a group header item (no checkbox, acts as a divider)
371
+ return new GroupHeaderListItem(sId, {
372
+ title: "{label}"
373
+ });
374
+ }
375
+
376
+ // Get the current filter value for highlighting
377
+ const sFilterValue = this._sCurrentFilterValue;
378
+
379
+ // Build the label text with optional parent property name
380
+ let sLabelText = oData.label || "";
381
+ if (oData.parentPropertyName && oData.duplicateName) {
382
+ sLabelText = `${sLabelText} (${oData.parentPropertyName})`;
383
+ }
384
+
385
+ // Create label with highlighted text if filter is active
386
+ const sHighlightedLabel = highlightText(sLabelText, sFilterValue);
387
+ const oLabelText = new FormattedText({
388
+ htmlText: sHighlightedLabel
389
+ });
390
+
391
+ // Build the original label text with highlighting
392
+ let oOriginalLabel;
393
+ if (oData.originalLabel) {
394
+ const sOriginalLabelText = this.oRTAResourceModel.getProperty("LBL_FREP").replace("{0}", oData.originalLabel);
395
+ const sHighlightedOriginal = highlightText(sOriginalLabelText, sFilterValue);
396
+ oOriginalLabel = new FormattedText({
397
+ htmlText: sHighlightedOriginal
398
+ });
399
+ }
400
+
401
+ const aVBoxItems = [oLabelText];
402
+ if (oOriginalLabel) {
403
+ aVBoxItems.push(oOriginalLabel);
404
+ }
405
+
406
+ const oVBox = new VBox({
407
+ items: aVBoxItems
408
+ });
409
+
410
+ return new CustomListItem(sId, {
411
+ content: [oVBox],
412
+ type: "Active",
413
+ selected: "{selected}",
414
+ tooltip: "{tooltip}"
415
+ }).addStyleClass("sapUIRtaListItem");
416
+ };
417
+
418
+ /**
419
+ * Resort the list by rebuilding it with sorted elements
197
420
  *
198
421
  * @private
199
422
  */
200
423
  AddElementsDialog.prototype._resortList = function() {
201
424
  this._bDescendingSortOrder = !this._bDescendingSortOrder;
202
- const oBinding = this._oList.getBinding("items");
203
- const aSorter = [];
204
- aSorter.push(new Sorter("label", this._bDescendingSortOrder));
205
- oBinding.sort(aSorter);
425
+ buildElementsList.call(this, this._oDialogModel.getProperty("/elements"), this._sCurrentFilterValue);
426
+ this._rebindList();
206
427
  };
207
428
 
208
429
  /**
209
- * Updates the model on filter events
430
+ * Updates the model on filter events by rebuilding the list with filtered elements
210
431
  *
211
432
  * @param {sap.ui.base.Event} oEvent event object
212
433
  * @private
213
434
  */
214
435
  AddElementsDialog.prototype._updateModelFilter = function(oEvent) {
215
436
  const sValue = oEvent.getParameter("newValue");
216
- const oBinding = this._oList.getBinding("items");
217
- if ((typeof sValue) === "string") {
218
- const oFilterLabel = new Filter("label", FilterOperator.Contains, sValue);
219
- const oOriginalLabelFilter = new Filter("originalLabel", FilterOperator.Contains, sValue);
220
- const oParentPropertyNameFilter = new Filter("parentPropertyName", FilterOperator.Contains, sValue);
221
- const oDuplicateNameFilter = new Filter("duplicateName", FilterOperator.EQ, true);
222
- const oParentNameFilter = new Filter({ filters: [oParentPropertyNameFilter, oDuplicateNameFilter], and: true });
223
- const oFilterLabelOrInfo = new Filter({ filters: [oFilterLabel, oOriginalLabelFilter, oParentNameFilter], and: false });
224
- oBinding.filter([oFilterLabelOrInfo]);
225
- } else {
226
- oBinding.filter([]);
437
+ this._sCurrentFilterValue = sValue;
438
+ buildElementsList.call(this, this._oDialogModel.getProperty("/elements"), sValue);
439
+ this._rebindList();
440
+ };
441
+
442
+ /**
443
+ * Rebinds the list items to force recreation with updated highlighting
444
+ *
445
+ * @private
446
+ */
447
+ AddElementsDialog.prototype._rebindList = function() {
448
+ if (this._oList) {
449
+ // Unbind and rebind to force factory function to be called again
450
+ this._oList.bindItems({
451
+ path: "/elementsFlat",
452
+ factory: this._createListItem.bind(this)
453
+ });
454
+ }
455
+ };
456
+
457
+ /**
458
+ * Checks if an element matches the filter criteria
459
+ *
460
+ * @param {object} oElement - The element to check
461
+ * @param {string} sFilterValue - The filter value to match
462
+ * @returns {boolean} True if the element matches the filter
463
+ * @private
464
+ */
465
+ AddElementsDialog.prototype._elementMatchesFilter = function(oElement, sFilterValue) {
466
+ const sLowerFilterValue = sFilterValue.toLowerCase();
467
+ // Check label
468
+ if (oElement.label?.toLowerCase().includes(sLowerFilterValue)) {
469
+ return true;
470
+ }
471
+ // Check originalLabel
472
+ if (oElement.originalLabel?.toLowerCase().includes(sLowerFilterValue)) {
473
+ return true;
474
+ }
475
+ // Check parentPropertyName (only for duplicates)
476
+ if (oElement.duplicateName && oElement.parentPropertyName?.toLowerCase().includes(sLowerFilterValue)) {
477
+ return true;
227
478
  }
479
+ return false;
228
480
  };
229
481
 
230
482
  /**
@@ -123,7 +123,7 @@ sap.ui.define([
123
123
  }
124
124
 
125
125
  function oPropertyToAdditionalElementInfo(oProperty) {
126
- return {
126
+ const oReturn = {
127
127
  selected: false,
128
128
  label: oProperty.label || oProperty.name,
129
129
  parentPropertyName: oProperty.parentPropertyName ? oProperty.parentPropertyName : "",
@@ -136,6 +136,10 @@ sap.ui.define([
136
136
  name: oProperty.name,
137
137
  bindingPath: oProperty.bindingPath
138
138
  };
139
+ if (oProperty.entityTypeDisplayName) {
140
+ oReturn.entityTypeDisplayName = oProperty.entityTypeDisplayName;
141
+ }
142
+ return oReturn;
139
143
  }
140
144
 
141
145
  function getLabel(oElement, mAction) {
@@ -152,7 +156,7 @@ sap.ui.define([
152
156
  function elementToAdditionalElementInfo(mData) {
153
157
  const oElement = mData.element;
154
158
  const sLabel = getLabel(oElement, mData.action);
155
- return {
159
+ const oReturn = {
156
160
  selected: false,
157
161
  label: oElement.__label || sLabel,
158
162
  tooltip: oElement.__tooltip || sLabel || oElement.__bindingPath,
@@ -165,6 +169,10 @@ sap.ui.define([
165
169
  elementId: oElement.getId(),
166
170
  sourceAggregation: mData.sourceAggregation
167
171
  };
172
+ if (oElement.__entityTypeDisplayName) {
173
+ oReturn.entityTypeDisplayName = oElement.__entityTypeDisplayName;
174
+ }
175
+ return oReturn;
168
176
  }
169
177
 
170
178
  /**
@@ -191,17 +199,36 @@ sap.ui.define([
191
199
  return [oElement];
192
200
  }
193
201
 
202
+ /**
203
+ * Marks properties with duplicate labels within the same entity type display name.
204
+ * The same entity can have different contexts (e.g. peer and manager both from Person entity),
205
+ * that's why we use the display name and not the entity type itself.
206
+ *
207
+ * @param {object[]} aProperties - Array of property objects
208
+ * @returns {object[]} - The same array with duplicateName flag set where applicable
209
+ */
194
210
  function checkForDuplicateProperties(aProperties) {
195
- aProperties.forEach(function(oModelProperty, index, aProperties) {
196
- if (oModelProperty.duplicateName !== true) {
197
- for (let j = index + 1; j < aProperties.length - 1; j++) {
198
- if (oModelProperty.label === aProperties[j].label) {
199
- oModelProperty.duplicateName = true;
200
- aProperties[j].duplicateName = true;
201
- }
202
- }
211
+ // Group properties by entityType and label to find duplicates
212
+ const mLabelsByEntityTypeDisplayName = {};
213
+
214
+ aProperties.forEach(function(oProperty) {
215
+ const sEntityTypeDisplayName = oProperty.entityTypeDisplayName || "";
216
+ const sLabel = oProperty.label || "";
217
+ const sKey = `${sEntityTypeDisplayName}|||${sLabel}`;
218
+
219
+ mLabelsByEntityTypeDisplayName[sKey] ||= [];
220
+ mLabelsByEntityTypeDisplayName[sKey].push(oProperty);
221
+ });
222
+
223
+ // Mark properties as duplicates if there are multiple with the same entityType display name and label
224
+ Object.values(mLabelsByEntityTypeDisplayName).forEach(function(aPropertiesWithSameLabel) {
225
+ if (aPropertiesWithSameLabel.length > 1) {
226
+ aPropertiesWithSameLabel.forEach(function(oProperty) {
227
+ oProperty.duplicateName = true;
228
+ });
203
229
  }
204
230
  });
231
+
205
232
  return aProperties;
206
233
  }
207
234
 
@@ -314,8 +341,10 @@ sap.ui.define([
314
341
  */
315
342
  function enhanceInvisibleElement(oInvisibleElement, mSomeItem) {
316
343
  oInvisibleElement.__originalLabel = mSomeItem.label;
317
-
318
344
  oInvisibleElement.__tooltip = mSomeItem.tooltip;
345
+ if (mSomeItem.entityTypeDisplayName) {
346
+ oInvisibleElement.__entityTypeDisplayName = mSomeItem.entityTypeDisplayName;
347
+ }
319
348
 
320
349
  // found element
321
350
  oInvisibleElement.__bindingPath = mSomeItem.name;
@@ -12,6 +12,7 @@ sap.ui.define([
12
12
  "sap/ui/core/Lib",
13
13
  "sap/ui/dt/OverlayRegistry",
14
14
  "sap/ui/dt/OverlayUtil",
15
+ "sap/ui/fl/util/CancelError",
15
16
  "sap/ui/fl/write/api/FieldExtensibility",
16
17
  "sap/ui/rta/plugin/additionalElements/ActionExtractor",
17
18
  "sap/ui/rta/plugin/additionalElements/AddElementsDialog",
@@ -28,6 +29,7 @@ sap.ui.define([
28
29
  Lib,
29
30
  OverlayRegistry,
30
31
  OverlayUtil,
32
+ CancelError,
31
33
  FieldExtensibility,
32
34
  ActionExtractor,
33
35
  AddElementsDialog,
@@ -119,7 +121,7 @@ sap.ui.define([
119
121
  * @class The plugin allows to add additional elements that exist either hidden in the UI or in the OData service
120
122
  * @extends sap.ui.rta.plugin.Plugin
121
123
  * @author SAP SE
122
- * @version 1.144.0
124
+ * @version 1.145.1
123
125
  * @constructor
124
126
  * @private
125
127
  * @since 1.44
@@ -323,8 +325,7 @@ sap.ui.define([
323
325
  const oOverlayToFocus = OverlayRegistry.getOverlay(vSiblingElement) || oResponsibleElementOverlay;
324
326
  oOverlayToFocus.focus();
325
327
  } catch (oError) {
326
- // no error means canceled dialog
327
- if (oError instanceof Error) {
328
+ if (!(oError instanceof CancelError)) {
328
329
  throw oError;
329
330
  }
330
331
  }
@@ -17,7 +17,7 @@ sap.ui.define([
17
17
  * Helper object containing methods for the AdditionalElements plugin
18
18
  *
19
19
  * @author SAP SE
20
- * @version 1.144.0
20
+ * @version 1.145.1
21
21
  * @private
22
22
  * @since 1.94
23
23
  */
@@ -25,7 +25,7 @@ sap.ui.define([
25
25
  * Helper object to build the RTA commands resulting from the AdditionalElements Plugin
26
26
  *
27
27
  * @author SAP SE
28
- * @version 1.144.0
28
+ * @version 1.145.1
29
29
  * @private
30
30
  * @since 1.94
31
31
  */
@@ -24,7 +24,7 @@
24
24
  <link>
25
25
  <Link text="{i18n>ANNOTATION_CHANGE_DIALOG_WARNING_MORE_INFO}"
26
26
  target="_blank"
27
- href="{path: '/', formatter: '.formatDocumentationUrl'}"/>
27
+ href="{/documentationUrl}"/>
28
28
  </link>
29
29
  </MessageStrip>
30
30
  <Label