@sapui5/sap.suite.ui.generic.template 1.148.1 → 1.148.3

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 (77) hide show
  1. package/package.json +1 -1
  2. package/src/sap/suite/ui/generic/template/.library +1 -1
  3. package/src/sap/suite/ui/generic/template/AnalyticalListPage/manifest.json +1 -1
  4. package/src/sap/suite/ui/generic/template/Canvas/manifest.json +1 -1
  5. package/src/sap/suite/ui/generic/template/ListReport/controller/ControllerImplementation.js +6 -3
  6. package/src/sap/suite/ui/generic/template/ListReport/manifest.json +1 -1
  7. package/src/sap/suite/ui/generic/template/ObjectPage/manifest.json +1 -1
  8. package/src/sap/suite/ui/generic/template/QuickCreate/manifest.json +1 -1
  9. package/src/sap/suite/ui/generic/template/QuickView/manifest.json +1 -1
  10. package/src/sap/suite/ui/generic/template/genericUtilities/controlStateWrapperFactory/SmartFilterBarWrapper.js +48 -8
  11. package/src/sap/suite/ui/generic/template/lib/AppComponent.js +1 -1
  12. package/src/sap/suite/ui/generic/template/lib/CRUDManager.js +7 -8
  13. package/src/sap/suite/ui/generic/template/lib/CommonEventHandlers.js +8 -1
  14. package/src/sap/suite/ui/generic/template/lib/CommonUtils.js +10 -2
  15. package/src/sap/suite/ui/generic/template/lib/MessageUtils.js +4 -3
  16. package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillAIOrchestrator.js +43 -12
  17. package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillApplyHandler.js +67 -218
  18. package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillDialogController.js +55 -8
  19. package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillFieldCollector.js +214 -35
  20. package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillFormRenderer.js +93 -18
  21. package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillHandler.js +426 -48
  22. package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillTableRenderer.js +512 -63
  23. package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/fragments/EasyFillDialog.fragment.xml +33 -23
  24. package/src/sap/suite/ui/generic/template/lib/ai/EasyFilterBarHandler.js +90 -73
  25. package/src/sap/suite/ui/generic/template/lib/i18n/i18n.properties +24 -0
  26. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ar.properties +26 -8
  27. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_bg.properties +26 -8
  28. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ca.properties +26 -8
  29. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_cnr.properties +26 -8
  30. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_cs.properties +26 -8
  31. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_cy.properties +26 -8
  32. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_da.properties +26 -8
  33. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_de.properties +30 -12
  34. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_el.properties +26 -8
  35. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_en.properties +26 -8
  36. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_en_GB.properties +26 -8
  37. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_en_US_saprigi.properties +26 -8
  38. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_es.properties +26 -8
  39. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_es_MX.properties +26 -8
  40. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_et.properties +26 -8
  41. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_fi.properties +26 -8
  42. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_fr.properties +29 -11
  43. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_fr_CA.properties +27 -9
  44. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_hi.properties +26 -8
  45. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_hr.properties +27 -9
  46. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_hu.properties +26 -8
  47. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_id.properties +26 -8
  48. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_it.properties +26 -8
  49. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_iw.properties +26 -8
  50. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ja.properties +26 -8
  51. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_kk.properties +26 -8
  52. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ko.properties +26 -8
  53. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_lt.properties +26 -8
  54. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_lv.properties +26 -8
  55. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_mk.properties +26 -8
  56. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ms.properties +26 -8
  57. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_nl.properties +26 -8
  58. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_no.properties +26 -8
  59. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_pl.properties +26 -8
  60. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_pt.properties +26 -8
  61. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_pt_PT.properties +26 -8
  62. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ro.properties +26 -8
  63. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ru.properties +26 -8
  64. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_sh.properties +26 -8
  65. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_sk.properties +26 -8
  66. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_sl.properties +26 -8
  67. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_sr.properties +26 -8
  68. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_sv.properties +37 -19
  69. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_th.properties +26 -8
  70. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_tr.properties +26 -8
  71. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_uk.properties +26 -8
  72. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_vi.properties +26 -8
  73. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_zh_CN.properties +26 -8
  74. package/src/sap/suite/ui/generic/template/lib/i18n/i18n_zh_TW.properties +26 -8
  75. package/src/sap/suite/ui/generic/template/lib/navigation/NavigationController.js +1 -1
  76. package/src/sap/suite/ui/generic/template/library.js +1 -1
  77. package/src/sap/suite/ui/generic/template/themes/base/ObjectPage.less +22 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sapui5/sap.suite.ui.generic.template",
3
- "version": "1.148.1",
3
+ "version": "1.148.3",
4
4
  "description": "SAPUI5 Library sap.suite.ui.generic.template",
5
5
  "keywords": [
6
6
  "sapui5",
@@ -7,7 +7,7 @@
7
7
 
8
8
  (c) Copyright 2009-2015 SAP SE. All rights reserved
9
9
  </copyright>
10
- <version>1.148.1</version>
10
+ <version>1.148.3</version>
11
11
 
12
12
  <documentation>Library with generic Suite UI templates.</documentation>
13
13
 
@@ -8,7 +8,7 @@
8
8
  "i18n": "i18n/i18n.properties",
9
9
  "applicationVersion": {
10
10
  "__comment": "applicationVersion oder componentversion??",
11
- "version": "1.148.1"
11
+ "version": "1.148.3"
12
12
  },
13
13
  "title": "{{TITLE}}",
14
14
  "description": "{{DESCRIPTION}}",
@@ -8,7 +8,7 @@
8
8
  "i18n": "i18n/i18n.properties",
9
9
  "applicationVersion": {
10
10
  "__comment": "applicationVersion oder componentversion??",
11
- "version": "1.148.1"
11
+ "version": "1.148.3"
12
12
  },
13
13
  "title": "Canvas",
14
14
  "description": "Canvas Page",
@@ -939,9 +939,12 @@ sap.ui.define([
939
939
  var oTempModel = oTemplateUtils.oComponentUtils.getTemplatePrivateModel();
940
940
  if (oTempModel.getProperty("/listReport/filterMode") === "easyFilter") {
941
941
  oSmartFilterbar.setVisible(false);
942
- var oTemplatePrivateModel = oTemplateUtils.oComponentUtils.getTemplatePrivateModel();
943
- oTemplatePrivateModel.setProperty("/listReport/firstSelection", true);
944
- oTemplatePrivateModel.setProperty("/generic/bDataAreShownInTable", false);
942
+ // Only show gray overlay when data in table is present.
943
+ // filters scenario where gray overlay shows up when No data Illustrated msg is rendered
944
+ if (oTempModel.getProperty("/generic/bDataAreShownInTable")) {
945
+ oTempModel.setProperty("/listReport/firstSelection", true);
946
+ oTempModel.setProperty("/generic/bDataAreShownInTable", false);
947
+ }
945
948
  } else {
946
949
  PXFeedback.triggerPXIntegration("toggleSwitchV2");
947
950
  oSmartFilterbar.setVisible(true);
@@ -8,7 +8,7 @@
8
8
  "i18n": "i18n/i18n.properties",
9
9
  "applicationVersion": {
10
10
  "__comment": "applicationVersion oder componentversion??",
11
- "version": "1.148.1"
11
+ "version": "1.148.3"
12
12
  },
13
13
  "title": "{{TITLE}}",
14
14
  "description": "{{DESCRIPTION}}",
@@ -6,7 +6,7 @@
6
6
  "type": "component",
7
7
  "i18n": "i18n/i18n.properties",
8
8
  "applicationVersion": {
9
- "version": "1.148.1"
9
+ "version": "1.148.3"
10
10
  },
11
11
  "title": "{{TITLE}}",
12
12
  "description": "{{DESCRIPTION}}",
@@ -6,7 +6,7 @@
6
6
  "type": "component",
7
7
  "i18n": "i18n/i18n.properties",
8
8
  "applicationVersion": {
9
- "version": "1.148.1"
9
+ "version": "1.148.3"
10
10
  },
11
11
  "title": "{{TITLE}}",
12
12
  "description": "{{DESCRIPTION}}",
@@ -6,7 +6,7 @@
6
6
  "type": "component",
7
7
  "i18n": "i18n/i18n.properties",
8
8
  "applicationVersion": {
9
- "version": "1.148.1"
9
+ "version": "1.148.3"
10
10
  },
11
11
  "title": "{{TITLE}}",
12
12
  "description": "{{DESCRIPTION}}",
@@ -27,6 +27,7 @@ sap.ui.define([
27
27
  var aBasicFilters = [];
28
28
  var oSmartFilterBar = oControl;
29
29
  var oEasyFilterCallbacks = null;
30
+ var oPendingEasyFilterState = null;
30
31
 
31
32
  var oVariantManagementInitializedPromise;
32
33
 
@@ -71,21 +72,47 @@ sap.ui.define([
71
72
  // after this has happened, we can get the custom data from SFB.
72
73
  oSmartFilterBar.attachAfterVariantLoad(function(){
73
74
  var oCustomData = oSmartFilterBar.getCustomFilterData();
75
+ var oGenericData;
76
+ if (oCustomData && oCustomData[dataPropertyNameGeneric]) {
77
+ oGenericData = oCustomData[dataPropertyNameGeneric];
78
+ } else {
79
+ // getCustomFilterData() returns null on cold start (no prior sap-iapp-state) because
80
+ // setCustomFilterData() is only called from beforeVariantFetch (variant save path),
81
+ // never during the initial LREP variant load. The _CUSTOM section is present in the
82
+ // variant content — fall back to reading it via getVariantContent().
83
+ try {
84
+ var oSVM = oSmartFilterBar.getSmartVariant();
85
+ // getCurrentVariantId() converts STANDARDVARIANTKEY to "" which _getVariantById can't look up.
86
+ // getCurrentVariantKey() returns the raw internal key and works for all variants.
87
+ var sVariantKey = oSVM && (oSVM.getCurrentVariantKey ? oSVM.getCurrentVariantKey() : oSVM.getStandardVariantKey());
88
+ var oVariantContent = oSVM && oSVM.getVariantContent(oSmartFilterBar, sVariantKey);
89
+ var oFilterBarVariant = oVariantContent && oVariantContent.filterBarVariant && JSON.parse(oVariantContent.filterBarVariant);
90
+ var oCustomSection = oFilterBarVariant && oFilterBarVariant._CUSTOM;
91
+ oGenericData = (oCustomSection && oCustomSection[dataPropertyNameGeneric]) || Object.create(null);
92
+ } catch (e) {
93
+ oGenericData = Object.create(null);
94
+ }
95
+ }
74
96
  // variant stored with 1.103 or later: all customFilter data stored in property customFilters
75
97
  // legacy variant stored with 1.102 or earlier: customFilters (from storing point of view) separated according to their origin
76
- var oCustomFiltersState = oCustomData[dataPropertyNameGeneric].customFilters || {
77
- editState: oCustomData[dataPropertyNameGeneric].editStateFilter,
78
- appExtension: oCustomData[dataPropertyNameCustom],
79
- adaptationExtensions: oCustomData[dataPropertyNameExtension]
98
+ var oCustomFiltersState = oGenericData.customFilters || {
99
+ editState: oGenericData.editStateFilter,
100
+ appExtension: oCustomData && oCustomData[dataPropertyNameCustom],
101
+ adaptationExtensions: oCustomData && oCustomData[dataPropertyNameExtension]
80
102
  };
81
103
  aBasicFilters = oSmartFilterBar.getAllFilterItems(true);
82
104
  mParams.oCustomFiltersWrapper.setState(oCustomFiltersState);
83
- oSVMWrapperCallbacks.setManagedControlStates(oCustomData[dataPropertyNameGeneric]);
105
+ oSVMWrapperCallbacks.setManagedControlStates(oGenericData);
84
106
  if (oEasyFilterCallbacks) {
85
107
  oEasyFilterCallbacks.setState({
86
- filterMode: oCustomData[dataPropertyNameGeneric].filterMode,
87
- easyFilter: oCustomData[dataPropertyNameGeneric].easyFilter
108
+ filterMode: oGenericData.filterMode,
109
+ easyFilter: oGenericData.easyFilter
88
110
  });
111
+ } else {
112
+ oPendingEasyFilterState = {
113
+ filterMode: oGenericData.filterMode,
114
+ easyFilter: oGenericData.easyFilter
115
+ };
89
116
  }
90
117
  });
91
118
 
@@ -142,7 +169,8 @@ sap.ui.define([
142
169
  .map(oFilterItem => oFilterItem.getName()),
143
170
  ...aRemovedFromStandard
144
171
  ])],
145
- customFilters: mParams.oCustomFiltersWrapper.getState()
172
+ customFilters: mParams.oCustomFiltersWrapper.getState(),
173
+ easyFilterState: oEasyFilterCallbacks ? oEasyFilterCallbacks.getState() : null
146
174
  };
147
175
  }
148
176
 
@@ -175,6 +203,14 @@ sap.ui.define([
175
203
 
176
204
  mParams.oCustomFiltersWrapper.setState(oState && oState.customFilters);
177
205
 
206
+ if (oState && oState.easyFilterState) {
207
+ if (oEasyFilterCallbacks) {
208
+ oEasyFilterCallbacks.setState(oState.easyFilterState);
209
+ } else {
210
+ oPendingEasyFilterState = oState.easyFilterState;
211
+ }
212
+ }
213
+
178
214
  // set visibility
179
215
  // TODO:
180
216
  // - How to deal with old states (not containing all information about visibility) -> legacy state handler?
@@ -250,6 +286,10 @@ sap.ui.define([
250
286
  setSVMWrapperCallbacks: setSVMWrapperCallbacks,
251
287
  setEasyFilterCallbacks: function(oCallbacks) {
252
288
  oEasyFilterCallbacks = oCallbacks;
289
+ if (oPendingEasyFilterState) {
290
+ oEasyFilterCallbacks.setState(oPendingEasyFilterState);
291
+ oPendingEasyFilterState = null;
292
+ }
253
293
  },
254
294
  bVMConnection: oSmartFilterBar.getSmartVariant(),
255
295
  suppressSelection: oSmartFilterBar.setSuppressSelection.bind(oSmartFilterBar), // if multiple reasons for suppressing overlap, a counter (to avoid to early resume) could be implemented here
@@ -959,7 +959,7 @@ sap.ui.define([
959
959
  * @public
960
960
  * @extends sap.ui.core.UIComponent
961
961
  * @author SAP SE
962
- * @version 1.148.1
962
+ * @version 1.148.3
963
963
  * @name sap.suite.ui.generic.template.lib.AppComponent
964
964
  */
965
965
  var oAppComponent = UIComponent.extend("sap.suite.ui.generic.template.lib.AppComponent", {
@@ -541,7 +541,13 @@ sap.ui.define(["sap/ui/base/Object",
541
541
  var aMessagesBeforeSave = CRUDHelper.fnGetMessagesFromContextFilter(oContextFilter, oMessageManager, true);
542
542
  var mMessagesBeforeSave = Object.create(null);
543
543
  aMessagesBeforeSave.forEach(function(oMessage){
544
- mMessagesBeforeSave[oMessage.getId()] = oMessage;
544
+ // Exclude transition messages (persistent === false) left over from a prior 412 response.
545
+ // Including them causes false-positive deduplication on retry: the new 412 produces
546
+ // the same message IDs, they are filtered out of aNewMessages, and fnHandleWarning
547
+ // is never called.
548
+ if (oMessage.persistent !== false) {
549
+ mMessagesBeforeSave[oMessage.getId()] = oMessage;
550
+ }
545
551
  });
546
552
 
547
553
  // Handles the 412 Warning case.
@@ -589,13 +595,6 @@ sap.ui.define(["sap/ui/base/Object",
589
595
  oServices.oTemplateCapabilities.oMessageButtonHelper.showMessagePopover();
590
596
  }
591
597
  }
592
- // Reset pending changes to prevent infinite loop when entering edit mode again.
593
- // Invalid values cause infinite loop because the pending changes (with invalid values) are resubmitted when the user clicks Edit, triggering the same error.
594
- var oContext = oController.getView().getBindingContext();
595
- var sContextPath = oContext && oContext.getPath();
596
- if (sContextPath && oModel && oModel.hasPendingChanges()) {
597
- oModel.resetChanges([sContextPath], undefined, true);
598
- }
599
598
  reject();
600
599
  });
601
600
  oBusyHelper.setBusy(oSubmitChange);
@@ -1417,8 +1417,15 @@ sap.ui.define(["sap/ui/base/Object",
1417
1417
  var oColumn = oSmartTableHandler.getColumnByKey(sColumnKey);
1418
1418
  //if the column is visible in the table, then only we bind the visible property of the cell
1419
1419
  if (oColumn && oColumn.getVisible()){
1420
+ // For UITable, getCells() only contains cells for visible columns (sap.ui.table.Table._getRowClone
1421
+ // skips invisible columns). indexOfColumn returns the position in the full columns aggregation
1422
+ // (including invisible), so we resolve the visible-column index instead to avoid an off-by-N
1423
+ // mismatch when columns have been deactivated. For ResponsiveTable, indexOfColumn is correct.
1424
+ var iCellIndex = controlHelper.isUiTable(oTable)
1425
+ ? oTable.getColumns().filter(function(c) { return c.getVisible(); }).indexOf(oColumn)
1426
+ : oTable.indexOfColumn(oColumn);
1420
1427
  aItems.forEach(function(oItem) {
1421
- var oCell = oItem.getCells()[oTable.indexOfColumn(oColumn)];
1428
+ var oCell = iCellIndex >= 0 ? oItem.getCells()[iCellIndex] : undefined;
1422
1429
  if (oCell) {
1423
1430
  // Only apply the binding if it is not already set with the correct path.
1424
1431
  // This avoids unnecessary teardown/recreation during scroll (rowsUpdated),
@@ -1020,7 +1020,6 @@ sap.ui.define(["sap/ui/base/Object",
1020
1020
  var oSelectionVariant, sSelectionVariantPrepared, sParameter, sSemanticObject, aSelVariantPropertyNames, aSelOptionPropertyNames, aParameterNames;
1021
1021
  var oEventParameters = oEvent.getParameters();
1022
1022
  var oNavigationHandler = oServices.oApplication.getNavigationHandler();
1023
- var SuppressionBehavior = FENavLibrary.SuppressionBehavior;
1024
1023
  // fill oSelectionVariant with the selectOptions from sSelectionVariant
1025
1024
  oSelectionVariant = oNavigationHandler.mixAttributesAndSelectionVariant({}, sSelectionVariant);
1026
1025
  //Invoke the "beforeSmartLinkPopoverOpensExtension" method to determine whether FE can process the event.
@@ -1068,7 +1067,16 @@ sap.ui.define(["sap/ui/base/Object",
1068
1067
  }
1069
1068
  });
1070
1069
  // add the resulting selectOptions and parameters (if any!) in oSelectionVariant with the ones of the semanticObject in oEventParameters as selectOptions to oSelectionVariant
1071
- oSelectionVariant = oNavigationHandler.mixAttributesAndSelectionVariant(mSemanticAttributesOfEventSemanticObject, oSelectionVariant.toJSONString(), SuppressionBehavior.ignoreEmptyString);
1070
+ // Only suppress empty-string properties that are not present in the empty-string semantic object bucket.
1071
+ // Properties in oSemObjEmpty are genuine entity key fields (e.g. MaintenanceOrderSubOperation:"") and must be kept.
1072
+ // Properties absent from oSemObjEmpty but present with "" in the event semantic object are spurious cache-inflated values and must be dropped.
1073
+ var mSemanticAttrsFiltered = Object.assign({}, mSemanticAttributesOfEventSemanticObject);
1074
+ Object.keys(mSemanticAttrsFiltered).forEach(function(sKey) {
1075
+ if (mSemanticAttrsFiltered[sKey] === "" && !(sKey in oSemObjEmpty)) {
1076
+ delete mSemanticAttrsFiltered[sKey];
1077
+ }
1078
+ });
1079
+ oSelectionVariant = oNavigationHandler.mixAttributesAndSelectionVariant(mSemanticAttrsFiltered, oSelectionVariant.toJSONString());
1072
1080
  // Remove sensitive data from the context
1073
1081
  oSelectionVariant = fnRemovePropertiesFromNavigationContext(oSelectionVariant, oEvent.getSource(), oState);
1074
1082
  var oObjectInfo = {
@@ -403,7 +403,8 @@ sap.ui.define([
403
403
  var fnFilter = oTemplateContract.oApplicationProxy.isTransientMessageNoCustomMessage;
404
404
  var sState; // Only one message which is a success (or info/None) message -> show as message toast
405
405
  // Remove transient messages that already exist in the error cache
406
- fnRemoveTransientMessages(isDuplicateMessage.bind(this));
406
+ // isDuplicateMessage is a plain closure function — no this binding needed
407
+ fnRemoveTransientMessages(isDuplicateMessage);
407
408
  var aTransientMessages = fnGetTransientMessages(false, fnFilter);
408
409
  if (aTransientMessages.length === 0) { // no transient messages -> immediate return
409
410
  return Promise.resolve();
@@ -658,8 +659,8 @@ sap.ui.define([
658
659
  }
659
660
  let oError;
660
661
  oError = JSON.parse(rawMessage);
661
- // Check if any cached error matches the parsed error
662
- return aWarningCache.some((oCachedError) => this.areMessagesSame(oCachedError, oError));
662
+ // areMessagesSame is a plain closure call it directly, no this needed
663
+ return aWarningCache.some((oCachedError) => areMessagesSame(oCachedError, oError));
663
664
  }
664
665
 
665
666
  /**
@@ -131,18 +131,28 @@ sap.ui.define([
131
131
  * - collectionFields: row-level updates for SmartTable collections
132
132
  *
133
133
  * Collection fields are identified by the isCollection flag in the field mapping.
134
- * Currently only the first valid collection is processed (single-table limitation).
134
+ * For tables that allow creation (mCollectionState.mCollectionAllowsCreation), rows
135
+ * without _rowIndex or _contextPath are treated as new rows to be created.
136
+ * Only one new row per table is supported; extra new rows are flagged via multipleNewRows.
137
+ * Tables where the AI proposed new rows but creation is not allowed are tracked in
138
+ * collectionsWithRejectedNewRows so the renderer can show a per-table warning strip.
135
139
  *
136
140
  * @param {object} oAiData - the AI response data map { fieldName: value | rowArray }
137
141
  * @param {object} mFieldMapping - the complete field mapping
138
142
  * @param {object} oFieldCollector - EasyFillFieldCollector (used for SmartTable validation)
139
143
  * @param {object} oObjectPage - the ObjectPage control (used for SmartTable validation)
140
- * @returns {{ simpleFields: object, collectionFields: object }}
144
+ * @param {object} mCollectionState - collection tracking state (used for allowsCreation check)
145
+ * @returns {{ simpleFields: object, collectionFields: object, attemptedMultipleNewRows: boolean, collectionsWithRejectedNewRows: object }}
141
146
  */
142
- splitAIResultByCollection: function(oAiData, mFieldMapping, oFieldCollector, oObjectPage) {
147
+ splitAIResultByCollection: function(oAiData, mFieldMapping, oFieldCollector, oObjectPage, mCollectionState) {
143
148
  var oSplitResult = {
144
149
  simpleFields: {},
145
- collectionFields: {}
150
+ collectionFields: {},
151
+ attemptedMultipleNewRows: false,
152
+ // Map of { navProperty: "all" | "mixed" } for tables where AI proposed new rows
153
+ // but creation is not allowed. "all" = only new rows proposed; "mixed" = some
154
+ // existing updates + some rejected new rows.
155
+ collectionsWithRejectedNewRows: {}
146
156
  };
147
157
 
148
158
  Object.keys(oAiData || {}).forEach(function(sFieldName) {
@@ -158,20 +168,41 @@ sap.ui.define([
158
168
  }
159
169
 
160
170
  if (oFieldMeta && oFieldMeta.isCollection === true && aCollectionRows) {
161
- // Validate that each row update has at least a context path or row index for binding
162
- var aRowUpdates = aCollectionRows.filter(function(oRow) {
171
+ var bAllowsCreation = !!(mCollectionState && mCollectionState.mCollectionAllowsCreation &&
172
+ mCollectionState.mCollectionAllowsCreation[sFieldName]);
173
+
174
+ // Separate existing-row updates (have _rowIndex or _contextPath) from new rows
175
+ var aExistingRowUpdates = aCollectionRows.filter(function(oRow) {
163
176
  return oRow && typeof oRow === "object" &&
164
177
  (typeof oRow._contextPath === "string" || typeof oRow._rowIndex === "number");
165
178
  });
179
+ var aRawNewRows = aCollectionRows.filter(function(oRow) {
180
+ return oRow && typeof oRow === "object" &&
181
+ typeof oRow._contextPath !== "string" &&
182
+ typeof oRow._rowIndex !== "number";
183
+ });
184
+
185
+ // Track tables where AI proposed new rows that cannot be created
186
+ if (!bAllowsCreation && aRawNewRows.length > 0) {
187
+ var sRejectionType = aExistingRowUpdates.length === 0 ? "all" : "mixed";
188
+ oSplitResult.collectionsWithRejectedNewRows[sFieldName] = sRejectionType;
189
+ }
190
+
191
+ var aNewRows = bAllowsCreation ? aRawNewRows : [];
192
+
193
+ // Cap new rows to one per table; flag if the AI proposed more
194
+ if (aNewRows.length > 1) {
195
+ oSplitResult.attemptedMultipleNewRows = true;
196
+ aNewRows = [aNewRows[0]];
197
+ }
198
+
199
+ var aRowUpdates = aExistingRowUpdates.concat(aNewRows);
166
200
 
167
- // Single-table limitation: only the first valid collection is accepted.
168
- // Future work: extend collectionFields structure to support multiple tables.
169
201
  var oValidation = oFieldCollector.isValidSmartTable(oFieldMeta.entitySet, oObjectPage);
170
- if (aRowUpdates.length > 0 &&
171
- Object.keys(oSplitResult.collectionFields).length === 0 &&
172
- oValidation.isValid) {
202
+ if (aRowUpdates.length > 0 && oValidation.isValid) {
173
203
  oSplitResult.collectionFields[sFieldName] = aRowUpdates;
174
- oLogger.debug("splitAIResultByCollection: accepted collection field '" + sFieldName + "' with " + aRowUpdates.length + " rows");
204
+ oLogger.debug("splitAIResultByCollection: accepted collection field '" + sFieldName + "' with " +
205
+ aExistingRowUpdates.length + " updates and " + aNewRows.length + " new row(s)");
175
206
  }
176
207
  } else {
177
208
  // Scalar field → goes to simpleFields