@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.
- package/package.json +1 -1
- package/src/sap/suite/ui/generic/template/.library +1 -1
- package/src/sap/suite/ui/generic/template/AnalyticalListPage/manifest.json +1 -1
- package/src/sap/suite/ui/generic/template/Canvas/manifest.json +1 -1
- package/src/sap/suite/ui/generic/template/ListReport/controller/ControllerImplementation.js +6 -3
- package/src/sap/suite/ui/generic/template/ListReport/manifest.json +1 -1
- package/src/sap/suite/ui/generic/template/ObjectPage/manifest.json +1 -1
- package/src/sap/suite/ui/generic/template/QuickCreate/manifest.json +1 -1
- package/src/sap/suite/ui/generic/template/QuickView/manifest.json +1 -1
- package/src/sap/suite/ui/generic/template/genericUtilities/controlStateWrapperFactory/SmartFilterBarWrapper.js +48 -8
- package/src/sap/suite/ui/generic/template/lib/AppComponent.js +1 -1
- package/src/sap/suite/ui/generic/template/lib/CRUDManager.js +7 -8
- package/src/sap/suite/ui/generic/template/lib/CommonEventHandlers.js +8 -1
- package/src/sap/suite/ui/generic/template/lib/CommonUtils.js +10 -2
- package/src/sap/suite/ui/generic/template/lib/MessageUtils.js +4 -3
- package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillAIOrchestrator.js +43 -12
- package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillApplyHandler.js +67 -218
- package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillDialogController.js +55 -8
- package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillFieldCollector.js +214 -35
- package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillFormRenderer.js +93 -18
- package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillHandler.js +426 -48
- package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/EasyFillTableRenderer.js +512 -63
- package/src/sap/suite/ui/generic/template/lib/ai/EasyFill/fragments/EasyFillDialog.fragment.xml +33 -23
- package/src/sap/suite/ui/generic/template/lib/ai/EasyFilterBarHandler.js +90 -73
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n.properties +24 -0
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ar.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_bg.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ca.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_cnr.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_cs.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_cy.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_da.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_de.properties +30 -12
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_el.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_en.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_en_GB.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_en_US_saprigi.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_es.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_es_MX.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_et.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_fi.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_fr.properties +29 -11
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_fr_CA.properties +27 -9
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_hi.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_hr.properties +27 -9
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_hu.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_id.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_it.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_iw.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ja.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_kk.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ko.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_lt.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_lv.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_mk.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ms.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_nl.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_no.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_pl.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_pt.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_pt_PT.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ro.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_ru.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_sh.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_sk.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_sl.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_sr.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_sv.properties +37 -19
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_th.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_tr.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_uk.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_vi.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_zh_CN.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/i18n/i18n_zh_TW.properties +26 -8
- package/src/sap/suite/ui/generic/template/lib/navigation/NavigationController.js +1 -1
- package/src/sap/suite/ui/generic/template/library.js +1 -1
- package/src/sap/suite/ui/generic/template/themes/base/ObjectPage.less +22 -1
package/package.json
CHANGED
|
@@ -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
|
-
|
|
943
|
-
|
|
944
|
-
|
|
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);
|
|
@@ -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 =
|
|
77
|
-
editState:
|
|
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(
|
|
105
|
+
oSVMWrapperCallbacks.setManagedControlStates(oGenericData);
|
|
84
106
|
if (oEasyFilterCallbacks) {
|
|
85
107
|
oEasyFilterCallbacks.setState({
|
|
86
|
-
filterMode:
|
|
87
|
-
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.
|
|
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
|
-
|
|
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()[
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
//
|
|
662
|
-
return aWarningCache.some((oCachedError) =>
|
|
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
|
-
*
|
|
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
|
-
* @
|
|
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
|
-
|
|
162
|
-
|
|
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 " +
|
|
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
|